⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xdesktopcontainer.cpp

📁 配合linux窗口管理器使用
💻 CPP
字号:
/* vim:tabstop=4:expandtab:shiftwidth=4 *  * Idesk -- XDesktopContainer.cpp * * Copyright (c) 2002, Chris (nikon) (nikon@sc.rr.com) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: *  *      Redistributions of source code must retain the above copyright *      notice, this list of conditions and the following disclaimer. *       *      Redistributions in binary form must reproduce the above copyright *      notice, this list of conditions and the following disclaimer in the *      documentation and/or other materials provided with the distribution. *       *      Neither the name of the <ORGANIZATION> nor the names of its *      contributors may be used to endorse or promote products derived from *      this software without specific prior written permission. * * (See the included file COPYING / BSD ) */#include "XDesktopContainer.h"#include "XIconWithShadow.h"#include "Database.h"extern "C" {#include "gdk-pixbuf-xlib/gdk-pixbuf-xlib.h"}XDesktopContainer::XDesktopContainer(AbstractApp * a) : DesktopContainer(a){    initXWin();    initImlib();}void XDesktopContainer::run(){    time[0] = 0; time[1] = 0; time[2] = 0;     numClicks[0] = 0; numClicks[1] = 0; numClicks[2] = 0;         configure();    loadIcons();    arrangeIcons();    eventLoop();}XDesktopContainer::~XDesktopContainer(){    Imlib_kill_image( imlibData, spareRoot );    for(unsigned int i = 0; i < iconList.size(); i++)        delete iconList[i];    delete config;}void XDesktopContainer::initXWin(){    display = XOpenDisplay(NULL);    rootWindow = DefaultRootWindow(display);    XSelectInput( display, rootWindow, PropertyChangeMask );}void XDesktopContainer::initImlib(){    imlibData = Imlib_init(display);    spareRoot = Imlib_create_image_from_drawable( imlibData, rootWindow, 0, 0, 0, WidthOfScreen( DefaultScreenOfDisplay( display ) ), HeightOfScreen( DefaultScreenOfDisplay( display ) ) );}void XDesktopContainer::configure(){        //get the user's config file    string ideskrcFile = getenv("HOME");    ideskrcFile += "/.ideskrc";    Database * db = new Database(ideskrcFile);    config = new DesktopConfig(db, ideskrcFile);    DesktopConfig * dConfig = dynamic_cast<DesktopConfig *>(config);    locked = dConfig->getLocked();    clickDelay = dConfig->getClickSpeed();    snapState = dConfig->getSnapState();    snapShadow = dConfig->getSnapShadow();    snapWidth = dConfig->getSnapWidth();    snapHeight = dConfig->getSnapHeight();    actionConfig = new ActionConfig(db, ideskrcFile);    delete db;}   void XDesktopContainer::loadIcons(){    AbstractIconConfig * iconPtr;    if (config->numIcons() == 0)    {        cout << "No icons loaded!! .idesktop is empty or contains invalid icons\n";        _exit(1);    }    else    {        //iterate through all the icons created by the configure class        for(iconPtr = config->start(); config->notFinished();            iconPtr = config->nextIcon())        {            DesktopIconConfig * dIconConfig =                dynamic_cast<DesktopIconConfig *>(iconPtr);            XIcon * icon;            if (dIconConfig->getSnapShadow() && dIconConfig->getSnapShadow())                icon = new XIconWithShadow(this, config, iconPtr);            else                icon = new XIcon(this, config, iconPtr);            addIcon(icon);        }    }}void XDesktopContainer::arrangeIcons(){    int maxW = 0;    int iconX, iconY = 20;    if( iconList.size() == 0 )    {        cout << "No Icons! Quitting.\n";        _exit(1);    }    for(unsigned int i = 0; i < iconList.size(); i++ )    {        XIcon *iPtr = dynamic_cast<XIcon *>(iconList[i]);        if( iPtr->getWidth() > maxW )            maxW = iPtr->getWidth();    }    iconX = WidthOfScreen(DefaultScreenOfDisplay(display)) - maxW - 20;    for(unsigned int i = 0; i < iconList.size(); i++ )    {        XIcon *iPtr = dynamic_cast<XIcon *>(iconList[i]);        if( iconY + iPtr->getHeight() + 30 + iPtr->getFontHeight() >                HeightOfScreen(DefaultScreenOfDisplay(display)) )        {            iconY = 20;            iconX = iconX - 20 - maxW;        }                if( iPtr->getX() == 0 && iPtr->getY() == 0 )        {            iPtr->setX(iconX + ((maxW - iPtr->getWidth())/2));            iPtr->setY(iconY);            iconY += iPtr->getHeight() + 30 + iPtr->getFontHeight();        }                iPtr->moveImageWindow();        iPtr->mapImageWindow();        //don't initially map caption for the hover effect        iPtr->initMapCaptionWindow();                iPtr->draw();    }}void XDesktopContainer::addIcon(AbstractIcon * icon){    iconList.push_back(icon);}XIcon * XDesktopContainer::findIcon(Window window){    for(unsigned int i = 0; i < iconList.size(); i++)    {        XIcon * tmpIcon = dynamic_cast<XIcon *> (iconList[i]);        Window * tmpCapWindow = tmpIcon->getCaptionWindow();        if ( *tmpIcon->getImageWindow() == window ||             (tmpCapWindow != NULL && *tmpCapWindow == window) )            return tmpIcon;    }    return None;}    void XDesktopContainer::eventLoop(){    XEvent ev;    for(;;)    {        XNextEvent(display, &ev);        event = ev;        parseEvent();    }}void XDesktopContainer::parseEvent(){    currentAction.clear();    parseNonIconEvents();    XIcon * icon = parseIconEvents();    exeCurrentAction(icon);}void XDesktopContainer::parseNonIconEvents(){    //check for background change, code taken and modified from aterm source    switch (event.type)    {        case PropertyNotify:            Atom atom = None ;            atom = XInternAtom(display, "_XROOTPMAP_ID", True);                        //changing background, lame fix is just to restart application            if (event.xproperty.atom == atom)                app->restartIdesk();            break;    }}XIcon * XDesktopContainer::parseIconEvents(){    XIcon * icon;    icon = findIcon(event.xmotion.window);    if (icon)    {        //XIcon * dIcon  = dynamic_cast<XIcon *>(icon);         switch (event.type)        {            case ButtonPress:                setEventState();                if (event.xbutton.button == Button1)                    currentAction.setLeft(hold);                else if (event.xbutton.button == Button2)                    currentAction.setMiddle(hold);                else if (event.xbutton.button == Button3)                    currentAction.setRight(hold);                                break;            case MotionNotify:                if (icon->isDragging() && !isLocked())                    icon->dragMotionNotify(event);                break;            case ButtonRelease:                setEventState();                if (event.xbutton.button == Button1)                    translateButtonRelease(0);                else if (event.xbutton.button == Button2)                    translateButtonRelease(1);                else if (event.xbutton.button == Button3)                    translateButtonRelease(2);                break;            case Expose: //only text can cause Expose event                //since we are redrawing the whole window we can ignore                //multiple expose events and only grab the last one                if (event.xexpose.count == 0)                    icon->drawText();                break;            case EnterNotify:                icon->mouseOverEffect();                break;            case LeaveNotify:                icon->mouseOffEffect();                break;        }    }    return icon;}void XDesktopContainer::exeCurrentAction(XIcon * icon){    if (actionConfig->getReload()->isOccuring(currentAction))        app->restartIdesk();        if (actionConfig->getLock()->isOccuring(currentAction))    {        toggleLock();        DesktopConfig * dConfig = dynamic_cast<DesktopConfig *>(config);        dConfig->saveLockState(locked);     }        if (icon) //make sure icon is not NULL    {        if (actionConfig->getDrag()->isOccuring(currentAction)            && !isLocked()            && !icon->isDragging() ) //only start drag if not already occuring            icon->dragButtonPress(event);        else if (actionConfig->getEndDrag()->isOccuring(currentAction))            icon->dragButtonRelease(event);        for (int i = 0; i < icon->getCommandArray().size() &&                        i < actionConfig->getExecuteActions().size();                        i++)            if (actionConfig->getExecuteAction(i)->isOccuring(currentAction))                runCommand(icon->getCommand(i));    }}void XDesktopContainer::setEventState(){    //cout << "State: " << oct << event.xbutton.state << endl;    currentAction.setControl(false);    currentAction.setShift(false);    currentAction.setAlt(false);    if (event.xbutton.state & ControlMask) currentAction.setControl(true);    if (event.xbutton.state & ShiftMask) currentAction.setShift(true);    if (event.xbutton.state & Mod1Mask) currentAction.setAlt(true);    if (event.xbutton.state & Button1Mask && currentAction.getLeft() == none)        currentAction.setLeft(hold);    if (event.xbutton.state & Button2Mask && currentAction.getMiddle() == none)        currentAction.setMiddle(hold);    if (event.xbutton.state & Button3Mask && currentAction.getRight() == none)        currentAction.setRight(hold);}    void XDesktopContainer::translateButtonRelease(int button){    if (event.xbutton.time - time[button] <= clickDelay)        numClicks[button]++;    else {        numClicks[button] = 1;        time[button] = event.xbutton.time;    }    if (numClicks[button] == 1)        currentAction.setButton(button, singleClk);    else if (numClicks[button] == 2)        currentAction.setButton(button, doubleClk);    else if (numClicks[button] >= 3)        currentAction.setButton(button, tripleClk);    else        currentAction.setButton(button, none);}void XDesktopContainer::saveState(){    //save each of the icons    for(unsigned int i = 0; i < iconList.size(); i++)        saveIcon(iconList[i]);    //general config saves        DesktopConfig * dConfig = dynamic_cast<DesktopConfig *>(config);    dConfig->saveLockState(locked);}void XDesktopContainer::saveIcon(AbstractIcon * xIcon){    xIcon->save();}void XDesktopContainer::reloadState(){    //TODO -- Reload all of the icons internally instead of rebooting whole    //        program. Not way too important though.}void XDesktopContainer::runCommand(const string & command){    //fork and execute program	if (!fork()) {		setsid();		execl("/bin/sh", "/bin/sh", "-c", command.c_str(), 0);		exit(0); //exit fork	}}int XDesktopContainer::widthOfScreen(){    return WidthOfScreen(DefaultScreenOfDisplay(display));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -