From 94100534be4d09a999ff6d7065e5fcf5364b8e99 Mon Sep 17 00:00:00 2001 From: fluxgen Date: Mon, 19 Apr 2004 22:44:42 +0000 Subject: kde dockapps in systray and moved resource templates to ScreenResource.cc --- src/Screen.cc | 504 +++++++++++++++++++--------------------------------------- src/Screen.hh | 8 +- 2 files changed, 167 insertions(+), 345 deletions(-) diff --git a/src/Screen.cc b/src/Screen.cc index d026f12..eef61c4 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.cc,v 1.274 2004/04/12 23:05:10 fluxgen Exp $ +// $Id: Screen.cc,v 1.275 2004/04/19 22:44:42 fluxgen Exp $ #include "Screen.hh" @@ -48,6 +48,7 @@ #include "SlitTheme.hh" #include "CommandParser.hh" #include "IconMenuItem.hh" +#include "AtomHandler.hh" #include "FbTk/Subject.hh" #include "FbTk/Directory.hh" @@ -57,6 +58,7 @@ #include "FbTk/MacroCommand.hh" #include "FbTk/StringUtil.hh" #include "FbTk/ImageControl.hh" +#include "FbTk/EventManager.hh" //use GNU extensions #ifndef _GNU_SOURCE @@ -69,6 +71,7 @@ #ifdef SLIT #include "Slit.hh" +#include "SlitClient.hh" #else // fill it in class Slit {}; @@ -154,265 +157,6 @@ private: } // End anonymous namespace -template <> -void FbTk::Resource::setDefaultValue() { - *(*this) = BScreen::ROWSMARTPLACEMENT; -} - -template <> -void FbTk::Resource::setFromString(const char *str) { - if (strcasecmp("RowSmartPlacement", str) == 0) - *(*this) = BScreen::ROWSMARTPLACEMENT; - else if (strcasecmp("ColSmartPlacement", str) == 0) - *(*this) = BScreen::COLSMARTPLACEMENT; - else if (strcasecmp("UnderMousePlacement", str) == 0) - *(*this) = BScreen::UNDERMOUSEPLACEMENT; - else if (strcasecmp("CascadePlacement", str) == 0) - *(*this) = BScreen::CASCADEPLACEMENT; - else - setDefaultValue(); - -} - -template <> -string FbTk::Resource::getString() { - switch (*(*this)) { - case BScreen::ROWSMARTPLACEMENT: - return "RowSmartPlacement"; - case BScreen::COLSMARTPLACEMENT: - return "ColSmartPlacement"; - case BScreen::UNDERMOUSEPLACEMENT: - return "UnderMousePlacement"; - case BScreen::CASCADEPLACEMENT: - return "CascadePlacement"; - } - - return "RowSmartPlacement"; -} - -template <> -void FbTk::Resource::setDefaultValue() { - *(*this) = BScreen::LEFTRIGHT; -} - -template <> -void FbTk::Resource::setFromString(const char *str) { - if (strcasecmp("LeftToRight", str) == 0) - *(*this) = BScreen::LEFTRIGHT; - else if (strcasecmp("RightToLeft", str) == 0) - *(*this) = BScreen::RIGHTLEFT; - else - setDefaultValue(); - -} - -template <> -string FbTk::Resource::getString() { - switch (*(*this)) { - case BScreen::LEFTRIGHT: - return "LeftToRight"; - case BScreen::RIGHTLEFT: - return "RightToLeft"; - } - - return "LeftToRight"; -} - - -template <> -void FbTk::Resource::setDefaultValue() { - *(*this) = BScreen::TOPBOTTOM; -} - -template <> -void FbTk::Resource::setFromString(const char *str) { - if (strcasecmp("TopToBottom", str) == 0) - *(*this) = BScreen::TOPBOTTOM; - else if (strcasecmp("BottomToTop", str) == 0) - *(*this) = BScreen::BOTTOMTOP; - else - setDefaultValue(); - -} - -template <> -string FbTk::Resource::getString() { - switch (*(*this)) { - case BScreen::TOPBOTTOM: - return "TopToBottom"; - case BScreen::BOTTOMTOP: - return "BottomToTop"; - } - - return "TopToBottom"; -} - -template <> -void FbTk::Resource::setDefaultValue() { - *(*this) = FbTk::MenuTheme::DELAY_OPEN; -} - -template <> -string FbTk::Resource::getString() { - switch (*(*this)) { - case FbTk::MenuTheme::DELAY_OPEN: - return string("Delay"); - case FbTk::MenuTheme::CLICK_OPEN: - return string("Click"); - } - return string("Delay"); -} - -template <> -void FbTk::Resource::setFromString(const char *str) { - if (strcasecmp(str, "Delay") == 0) - *(*this) = FbTk::MenuTheme::DELAY_OPEN; - else if (strcasecmp(str, "Click") == 0) - *(*this) = FbTk::MenuTheme::CLICK_OPEN; - else - setDefaultValue(); -} - -template<> -std::string FbTk::Resource:: -getString() { - switch (m_value) { - case BScreen::SLOPPYFOCUS: - return string("SloppyFocus"); - case BScreen::SEMISLOPPYFOCUS: - return string("SemiSloppyFocus"); - case BScreen::CLICKTOFOCUS: - return string("ClickToFocus"); - } - // default string - return string("ClickToFocus"); -} - -template<> -void FbTk::Resource:: -setFromString(char const *strval) { - // auto raise options here for backwards read compatibility - // they are not supported for saving purposes. Nor does the "AutoRaise" - // part actually do anything - if (strcasecmp(strval, "SloppyFocus") == 0 - || strcasecmp(strval, "AutoRaiseSloppyFocus") == 0) - m_value = BScreen::SLOPPYFOCUS; - else if (strcasecmp(strval, "SemiSloppyFocus") == 0 - || strcasecmp(strval, "AutoRaiseSemiSloppyFocus") == 0) - m_value = BScreen::SEMISLOPPYFOCUS; - else if (strcasecmp(strval, "ClickToFocus") == 0) - m_value = BScreen::CLICKTOFOCUS; - else - setDefaultValue(); -} - -template<> -void FbTk::Resource::setDefaultValue() { - *(*this) = FbTk::GContext::LINESOLID; -} - -template<> -std::string FbTk::Resource::getString() { - switch(m_value) { - case FbTk::GContext::LINESOLID: - return "LineSolid"; - break; - case FbTk::GContext::LINEONOFFDASH: - return "LineOnOffDash"; - break; - case FbTk::GContext::LINEDOUBLEDASH: - return "LineDoubleDash"; - break; - }; -} - -template<> -void FbTk::Resource -::setFromString(char const *strval) { - - if (strcasecmp(strval, "LineSolid") == 0 ) - m_value = FbTk::GContext::LINESOLID; - else if (strcasecmp(strval, "LineOnOffDash") == 0 ) - m_value = FbTk::GContext::LINEONOFFDASH; - else if (strcasecmp(strval, "LineDoubleDash") == 0) - m_value = FbTk::GContext::LINEDOUBLEDASH; - else - setDefaultValue(); -} - -template<> -void FbTk::Resource::setDefaultValue() { - *(*this) = FbTk::GContext::JOINMITER; -} - -template<> -std::string FbTk::Resource::getString() { - switch(m_value) { - case FbTk::GContext::JOINMITER: - return "JoinMiter"; - break; - case FbTk::GContext::JOINBEVEL: - return "JoinBevel"; - break; - case FbTk::GContext::JOINROUND: - return "JoinRound"; - break; - }; -} - -template<> -void FbTk::Resource -::setFromString(char const *strval) { - - if (strcasecmp(strval, "JoinRound") == 0 ) - m_value = FbTk::GContext::JOINROUND; - else if (strcasecmp(strval, "JoinMiter") == 0 ) - m_value = FbTk::GContext::JOINMITER; - else if (strcasecmp(strval, "JoinBevel") == 0) - m_value = FbTk::GContext::JOINBEVEL; - else - setDefaultValue(); -} - -template<> -void FbTk::Resource::setDefaultValue() { - *(*this) = FbTk::GContext::CAPNOTLAST; -} - -template<> -std::string FbTk::Resource::getString() { - switch(m_value) { - case FbTk::GContext::CAPNOTLAST: - return "CapNotLast"; - break; - case FbTk::GContext::CAPBUTT: - return "CapButt"; - break; - case FbTk::GContext::CAPROUND: - return "CapRound"; - break; - case FbTk::GContext::CAPPROJECTING: - return "CapProjecting"; - break; - }; -} - -template<> -void FbTk::Resource -::setFromString(char const *strval) { - - if (strcasecmp(strval, "CapNotLast") == 0 ) - m_value = FbTk::GContext::CAPNOTLAST; - else if (strcasecmp(strval, "CapProjecting") == 0 ) - m_value = FbTk::GContext::CAPPROJECTING; - else if (strcasecmp(strval, "CapRound") == 0) - m_value = FbTk::GContext::CAPROUND; - else if (strcasecmp(strval, "CapButt" ) == 0) - m_value = FbTk::GContext::CAPBUTT; - else - setDefaultValue(); -} - namespace { class StyleMenuItem: public FbTk::MenuItem { @@ -710,18 +454,59 @@ BScreen::BScreen(FbTk::ResourceManager &rm, *resource.gc_cap_style, *resource.gc_join_style); - int i; + rm.unlock(); + + + XFlush(disp); +} + +template +void destroyAndClearList(A &a) { + typedef typename A::iterator iterator; + iterator it = a.begin(); + iterator it_end = a.end(); + for (; it != it_end; ++it) + delete (*it); + + a.clear(); +} + +BScreen::~BScreen() { + if (! managed) + return; + + if (m_rootmenu.get() != 0) + m_rootmenu->removeAll(); + + if (geom_pixmap != None) + imageControl().removeImage(geom_pixmap); + + if (pos_pixmap != None) + imageControl().removeImage(pos_pixmap); + + removeWorkspaceNames(); + + destroyAndClearList(m_workspaces_list); + destroyAndClearList(m_icon_list); + destroyAndClearList(m_netizen_list); + + if (hasXinerama() && m_xinerama_headinfo) { + delete [] m_xinerama_headinfo; + } +} + +void BScreen::initWindows() { unsigned int nchild; Window r, p, *children; + Display *disp = FbTk::App::instance()->display(); XQueryTree(disp, rootWindow().window(), &r, &p, &children, &nchild); // preen the window list of all icon windows... for better dockapp support - for (i = 0; i < (int) nchild; i++) { + for (int i = 0; i < (int) nchild; i++) { if (children[i] == None) continue; - XWMHints *wmhints = XGetWMHints(FbTk::App::instance()->display(), - children[i]); + XWMHints *wmhints = XGetWMHints(disp, children[i]); if (wmhints) { if ((wmhints->flags & IconWindowHint) && @@ -737,7 +522,8 @@ BScreen::BScreen(FbTk::ResourceManager &rm, } // manage shown windows - for (i = 0; i < (int) nchild; ++i) { + Fluxbox *fluxbox = Fluxbox::instance(); + for (int i = 0; i < (int) nchild; ++i) { if (children[i] == None || (! fluxbox->validateWindow(children[i]))) continue; @@ -759,46 +545,8 @@ BScreen::BScreen(FbTk::ResourceManager &rm, } } - rm.unlock(); - XFree(children); - XFlush(disp); -} - -template -void destroyAndClearList(A &a) { - typedef typename A::iterator iterator; - iterator it = a.begin(); - iterator it_end = a.end(); - for (; it != it_end; ++it) - delete (*it); - - a.clear(); -} - -BScreen::~BScreen() { - if (! managed) - return; - - if (m_rootmenu.get() != 0) - m_rootmenu->removeAll(); - - if (geom_pixmap != None) - imageControl().removeImage(geom_pixmap); - - if (pos_pixmap != None) - imageControl().removeImage(pos_pixmap); - - removeWorkspaceNames(); - - destroyAndClearList(m_workspaces_list); - destroyAndClearList(m_icon_list); - destroyAndClearList(m_netizen_list); - - if (hasXinerama() && m_xinerama_headinfo) { - delete [] m_xinerama_headinfo; - } } unsigned int BScreen::currentWorkspaceID() const { @@ -1371,63 +1119,114 @@ void BScreen::updateNetizenConfigNotify(XEvent &e) { (*it)->sendConfigNotify(e); } -FluxboxWindow *BScreen::createWindow(Window client) { - FbTk::App::instance()->sync(false); +bool BScreen::isKdeDockapp(Window client) const { + //Check and see if client is KDE dock applet. + //If so add to Slit + bool iskdedockapp = false; + Atom ajunk; + int ijunk; + unsigned long *data = 0, uljunk; + Display *disp = FbTk::App::instance()->display(); + // Check if KDE v2.x dock applet + if (XGetWindowProperty(disp, client, + XInternAtom(FbTk::App::instance()->display(), + "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False), + 0l, 1l, False, + XA_WINDOW, &ajunk, &ijunk, &uljunk, + &uljunk, (unsigned char **) &data) == Success) { + + if (data) + iskdedockapp = true; + XFree((void *) data); + data = 0; + } -#ifdef SLIT -#ifdef KDE - //Check and see if client is KDE dock applet. - //If so add to Slit - bool iskdedockapp = false; - Atom ajunk; - int ijunk; - unsigned long *data = 0, uljunk; - Display *disp = FbTk::App::instance()->display(); - // Check if KDE v2.x dock applet + // Check if KDE v1.x dock applet + if (!iskdedockapp) { + Atom kwm1 = XInternAtom(FbTk::App::instance()->display(), + "KWM_DOCKWINDOW", False); if (XGetWindowProperty(disp, client, - XInternAtom(FbTk::App::instance()->display(), - "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False), - 0l, 1l, False, - XA_WINDOW, &ajunk, &ijunk, &uljunk, - &uljunk, (unsigned char **) &data) == Success) { - - if (data) - iskdedockapp = True; + kwm1, 0l, 1l, False, + kwm1, &ajunk, &ijunk, &uljunk, + &uljunk, (unsigned char **) &data) == Success && data) { + iskdedockapp = (data && data[0] != 0); XFree((void *) data); data = 0; } + } - // Check if KDE v1.x dock applet - if (!iskdedockapp) { - Atom kwm1 = XInternAtom(FbTk::App::instance()->display(), - "KWM_DOCKWINDOW", False); - if (XGetWindowProperty(disp, client, - kwm1, 0l, 1l, False, - kwm1, &ajunk, &ijunk, &uljunk, - &uljunk, (unsigned char **) &data) == Success && data) { - iskdedockapp = (data && data[0] != 0); - XFree((void *) data); - data = 0; - } + return iskdedockapp; +} + +bool BScreen::addKdeDockapp(Window client) { + + XSelectInput(FbTk::App::instance()->display(), client, StructureNotifyMask); + char intbuff[16]; + sprintf(intbuff, "%d", screenNumber()); + std::string atom_name("_NET_SYSTEM_TRAY_S"); + atom_name += intbuff; // append number + AtomHandler *handler = Fluxbox::instance()->getAtomHandler(atom_name); + FbTk::EventHandler *evh = 0; + FbTk::EventManager *evm = FbTk::EventManager::instance(); + if (handler == 0) { +#ifdef SLIT + if (slit() != 0) + slit()->addClient(client); + else +#endif // SLIT + return false; + } else { + WinClient winclient(client, *this); + handler->setupClient(winclient); + // we need to save old handler and re-add it later + evh = evm->find(client); + } + + if (evh != 0) // re-add handler + evm->add(*evh, client); + + return true; +} + +void BScreen::setupKdeDockapps() { +#ifdef SLIT + if (slit() == 0) + return; + // kde dockapps end up in the slit at start + Slit::SlitClients::iterator it = slit()->clients().begin(); + Slit::SlitClients::iterator it_end = slit()->clients().end(); + std::list winlist; + for (; it != it_end; ++it) { + if (isKdeDockapp((*it)->window())) { + winlist.push_back((*it)->window()); + slit()->removeClient((*it)->window()); } + } + std::list::iterator win_it = winlist.begin(); + std::list::iterator win_it_end = winlist.end(); + for (; win_it != win_it_end; ++win_it) { + createWindow(*win_it); + } +#endif // SLIT +} - if (iskdedockapp) { - XSelectInput(disp, client, StructureNotifyMask); +FluxboxWindow *BScreen::createWindow(Window client) { + FbTk::App::instance()->sync(false); - if (slit()) - slit()->addClient(client); + if (isKdeDockapp(client)) { + if (addKdeDockapp(client)) { return 0; // dont create a FluxboxWindow for this one } -#endif // KDE -#endif // SLIT + } WinClient *winclient = new WinClient(client, *this); if (winclient->initial_state == WithdrawnState) { delete winclient; #ifdef SLIT - slit()->addClient(client); + if (slit()) + slit()->addClient(client); #endif // SLIT return 0; } @@ -1487,14 +1286,31 @@ FluxboxWindow *BScreen::createWindow(Window client) { return win; } + FluxboxWindow *BScreen::createWindow(WinClient &client) { FluxboxWindow *win = new FluxboxWindow(client, winFrameTheme(), *layerManager().getLayer(Fluxbox::instance()->getNormalLayer())); + + if (isKdeDockapp(client.window())) { + if (addKdeDockapp(client.window())) { + // we need to save old handler and readd it later + FbTk::EventManager *evm = FbTk::EventManager::instance(); + FbTk::EventHandler *evh = evm->find(client.window()); + delete win; + evm->add(*evh, client.window()); + return 0; + } + } else { + #ifdef SLIT - if (win->initialState() == WithdrawnState) - slit()->addClient(win->clientWindow()); + if (win->initialState() == WithdrawnState && slit() != 0) { + slit()->addClient(win->clientWindow()); + } #endif // SLIT + } + + if (!win->isManaged()) { delete win; return 0; diff --git a/src/Screen.hh b/src/Screen.hh index 6731d14..cb08d06 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.hh,v 1.138 2004/04/12 23:05:10 fluxgen Exp $ +// $Id: Screen.hh,v 1.139 2004/04/19 22:44:42 fluxgen Exp $ #ifndef SCREEN_HH #define SCREEN_HH @@ -88,6 +88,7 @@ public: int scrn, int number_of_layers); ~BScreen(); + void initWindows(); inline bool isSloppyFocus() const { return (*resource.focus_model == SLOPPYFOCUS); } inline bool isSemiSloppyFocus() const { return (*resource.focus_model == SEMISLOPPYFOCUS); } inline bool isRootColormapInstalled() const { return root_colormap_installed; } @@ -134,6 +135,11 @@ public: unsigned int maxRight(int head) const; unsigned int maxTop(int head) const; unsigned int maxBottom(int head) const; + /// @return true if window is kde dock app + bool isKdeDockapp(Window win) const; + /// @return true if dock app was added, else false + bool addKdeDockapp(Window win); + void setupKdeDockapps(); inline unsigned int width() const { return rootWindow().width(); } inline unsigned int height() const { return rootWindow().height(); } -- cgit v0.11.2