📄 xdesktopcontainer.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 + -