From 80b10f7772b91f1f4a61eace4e5235a79060e1f0 Mon Sep 17 00:00:00 2001 From: Henrik Kinnunen Date: Sun, 27 Apr 2008 21:22:18 +0200 Subject: Added SimpleObserver class. This class works in the same way as the SimpleCommand class. Use it with the makeObserver function. It calls the receiver's member function when the subject sends a signal. --- src/FbTk/Makefile.am | 2 +- src/FbTk/SimpleObserver.hh | 70 ++++++++++++++++++++++++++++++++++++++++++++++ src/SendToMenu.cc | 31 ++++++++++---------- src/SendToMenu.hh | 23 +++++++++++---- src/SystemTray.cc | 15 ++++++---- src/SystemTray.hh | 11 ++++---- src/Toolbar.cc | 37 +++++++++++------------- src/Toolbar.hh | 8 +++--- 8 files changed, 139 insertions(+), 58 deletions(-) create mode 100644 src/FbTk/SimpleObserver.hh diff --git a/src/FbTk/Makefile.am b/src/FbTk/Makefile.am index 6fa874a..fcf0304 100644 --- a/src/FbTk/Makefile.am +++ b/src/FbTk/Makefile.am @@ -44,7 +44,7 @@ libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \ StringUtil.hh StringUtil.cc Parser.hh Parser.cc \ RegExp.hh RegExp.cc \ FbString.hh FbString.cc \ - Subject.hh Subject.cc Observer.hh Observer.cc \ + Subject.hh Subject.cc Observer.hh Observer.cc SimpleObserver.hh \ Transparent.hh Transparent.cc \ FbPixmap.hh FbPixmap.cc \ FbDrawable.hh FbDrawable.cc \ diff --git a/src/FbTk/SimpleObserver.hh b/src/FbTk/SimpleObserver.hh new file mode 100644 index 0000000..aafdf59 --- /dev/null +++ b/src/FbTk/SimpleObserver.hh @@ -0,0 +1,70 @@ +// SimpleObserver.hh +// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#include "Observer.hh" +#include "SimpleCommand.hh" + +namespace FbTk { + +/** Functor for observers, instead of using this directly use makeObserver. + * Usage: + * @code + * class SomeClass { + * public: + * void doAction(); + * }; + * + * SomeClass some; + * + * Observer* obs = makeProxyObserver(some, &SomeClass::doAction); + * SomeSubject subj; + * subj.attach(obs); + * @endcode + */ +template +class SimpleObserver: public Observer { +public: + typedef void (Receiver::* Action)(); + SimpleObserver(Receiver &r, Action a): + m_receiver(r), m_action(a) { + + } + void update(Subject *changedSubj) { + (m_receiver.*m_action)(); + } +private: + Receiver &m_receiver; + Action m_action; +}; + +// Helpers +/** Creates an observer that takes no arguments. + * @param receiver The receiving instance. + * @param action A function in the receiving class. + * @return allocated simple observer. @see SimpleObserver + */ +template +Observer *makeObserver(Receiver &receiver, Action action) { + return new SimpleObserver( receiver, action ); +} + +} + diff --git a/src/SendToMenu.cc b/src/SendToMenu.cc index ae261b9..8ec2094 100644 --- a/src/SendToMenu.cc +++ b/src/SendToMenu.cc @@ -1,5 +1,5 @@ // SendToMenu.cc for Fluxbox -// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org) +// Copyright (c) 2003 - 2008 Henrik Kinnunen (fluxgen at fluxbox dot org) // and Simon Bowden (rathnor at users.sourceforge.net) // // Permission is hereby granted, free of charge, to any person obtaining a @@ -31,6 +31,7 @@ #include "FbTk/MultiButtonMenuItem.hh" #include "FbTk/Command.hh" +#include "FbTk/SimpleObserver.hh" class SendToCmd: public FbTk::Command { public: @@ -54,24 +55,21 @@ SendToMenu::SendToMenu(BScreen &screen): // workspace count signal // workspace names signal // current workspace signal - screen.workspaceCountSig().attach(this); - screen.workspaceNamesSig().attach(this); - screen.currentWorkspaceSig().attach(this); - + m_rebuildObs = makeObserver(*this, &SendToMenu::rebuildMenu); + screen.workspaceCountSig().attach(m_rebuildObs); + screen.workspaceNamesSig().attach(m_rebuildObs); + screen.currentWorkspaceSig().attach(m_rebuildObs); + // no title for this menu, it should be a submenu in the window menu. disableTitle(); - // build menu - update(0); + // setup menu items + rebuildMenu(); } -void SendToMenu::update(FbTk::Subject *subj) { - if (subj != 0) { - if (subj == &(theme().reconfigSig())) { - // we got reconfig Theme signal, let base menu handle it - FbTk::Menu::update(subj); - return; - } - - } +SendToMenu::~SendToMenu() { + delete m_rebuildObs; +} + +void SendToMenu::rebuildMenu() { // rebuild menu removeAll(); @@ -95,6 +93,7 @@ void SendToMenu::show() { if (WindowCmd::window() != 0) { for (unsigned int i=0; i < numberOfItems(); ++i) setItemEnabled(i, true); + // update the workspace for the current window setItemEnabled(WindowCmd::window()->workspaceNumber(), false); updateMenu(); } diff --git a/src/SendToMenu.hh b/src/SendToMenu.hh index 7754987..0f668a9 100644 --- a/src/SendToMenu.hh +++ b/src/SendToMenu.hh @@ -1,5 +1,5 @@ // SendToMenu.hh for Fluxbox -// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org) +// Copyright (c) 2003 - 2008 Henrik Kinnunen (fluxgen at fluxbox dot org) // and Simon Bowden (rathnor at users.sourceforge.net) // // Permission is hereby granted, free of charge, to any person obtaining a @@ -25,15 +25,28 @@ #include "FbMenu.hh" +namespace FbTk { +class Observer; +} + class BScreen; +/** + * Creates the "send to menu". + * Displays all the workspaces for which the current window can be sent to. + */ class SendToMenu:public FbMenu { public: - explicit SendToMenu(BScreen &win); - virtual ~SendToMenu() { } + /// @param screen the screen on which this menu should be created on. + explicit SendToMenu(BScreen &screen); + virtual ~SendToMenu(); + /// @see FbTk::Menu void show(); -protected: - void update(FbTk::Subject *subj); +private: + /// Rebuild the menu from scratch. + void rebuildMenu(); + /// listens to signals that makes this instance need to rebuild menu + FbTk::Observer *m_rebuildObs; }; #endif // SENDTOMENU_HH diff --git a/src/SystemTray.cc b/src/SystemTray.cc index 4275099..699ca47 100644 --- a/src/SystemTray.cc +++ b/src/SystemTray.cc @@ -30,6 +30,7 @@ #include "WinClient.hh" #include "Screen.hh" #include "ButtonTheme.hh" +#include "SimpleObserver.hh" #include #include @@ -166,8 +167,10 @@ SystemTray::SystemTray(const FbTk::FbWindow& parent, FbTk::EventManager::instance()->add(*this, m_window); FbTk::EventManager::instance()->add(*this, m_selection_owner); - m_theme->reconfigSig().attach(this); - screen.bgChangeSig().attach(this); + // setup signals + m_observer.reset(makeObserver(*this, &SystemTray::update)); + m_theme->reconfigSig().attach(m_observer.get()); + screen.bgChangeSig().attach(m_observer.get()); Fluxbox* fluxbox = Fluxbox::instance(); Display *disp = fluxbox->display(); @@ -216,7 +219,7 @@ SystemTray::SystemTray(const FbTk::FbWindow& parent, XSendEvent(disp, root_window, false, StructureNotifyMask, &ce); - update(0); + update(); } SystemTray::~SystemTray() { @@ -276,7 +279,7 @@ void SystemTray::hide() { void SystemTray::show() { - update(0); + update(); m_window.show(); } @@ -470,7 +473,7 @@ void SystemTray::rearrangeClients() { unsigned int trayw = m_num_visible_clients*h_rot0 + bw, trayh = h_rot0; FbTk::translateSize(orientation(), trayw, trayh); resize(trayw, trayh); - update(0); + update(); // move and resize clients ClientList::iterator client_it = m_clients.begin(); @@ -529,7 +532,7 @@ void SystemTray::showClient(TrayWindow *traywin) { rearrangeClients(); } -void SystemTray::update(FbTk::Subject* subject) { +void SystemTray::update() { if (!m_theme->texture().usePixmap()) { m_window.setBackgroundColor(m_theme->texture().color()); diff --git a/src/SystemTray.hh b/src/SystemTray.hh index 3215e31..132069a 100644 --- a/src/SystemTray.hh +++ b/src/SystemTray.hh @@ -25,12 +25,12 @@ #include "FbTk/FbWindow.hh" #include "FbTk/EventHandler.hh" -#include "FbTk/Observer.hh" #include "ToolTheme.hh" #include "ToolbarItem.hh" #include +#include class BScreen; class ButtonTheme; @@ -39,9 +39,10 @@ class AtomHandler; namespace FbTk { template class ThemeProxy; +class Observer; } -class SystemTray: public ToolbarItem, public FbTk::EventHandler, public FbTk::Observer { +class SystemTray: public ToolbarItem, public FbTk::EventHandler { public: explicit SystemTray(const FbTk::FbWindow &parent, @@ -75,7 +76,7 @@ public: m_window.setBorderWidth(m_theme->border().width()); m_window.setBorderColor(m_theme->border().color()); m_window.setAlpha(alpha); - update(0); + update(); } void updateSizing() { m_window.setBorderWidth(m_theme->border().width()); } @@ -85,7 +86,7 @@ public: private: - void update(FbTk::Subject *subj); + void update(); typedef std::list ClientList; ClientList::iterator findClient(Window win); @@ -108,7 +109,7 @@ private: // gaim/pidgin seems to barf if the selection is not an independent window. // I suspect it's an interacton with parent relationship and gdk window caching. FbTk::FbWindow m_selection_owner; - + std::auto_ptr m_observer; }; #endif // SYSTEMTRAY_HH diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 26d87a8..540ceb9 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -50,7 +50,7 @@ #include "FbTk/BoolMenuItem.hh" #include "FbTk/IntMenuItem.hh" #include "FbTk/Shape.hh" - +#include "FbTk/SimpleObserver.hh" // use GNU extensions #ifndef _GNU_SOURCE @@ -240,11 +240,15 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, size_t width): m_shape(new FbTk::Shape(frame.window, 0)), m_resize_lock(false) { _FB_USES_NLS; + // NOTE: first subject is always the rearrangeItem ! + m_observers.push_back(makeObserver(*this, &Toolbar::rearrangeItems)); // we need to get notified when the theme is reloaded - m_theme.reconfigSig().attach(this); + m_observers.push_back(makeObserver(*this, &Toolbar::reconfigure)); + m_theme.reconfigSig().attach(m_observers.back()); + screen().reconfigureSig().attach(m_observers.back()); // get this on antialias change // listen to screen size changes - screen().resizeSig().attach(this); - screen().reconfigureSig().attach(this); // get this on antialias change + screen().resizeSig().attach(m_observers.back()); + moveToLayer((*m_rc_layernum).getNum()); @@ -370,6 +374,7 @@ void Toolbar::lower() { } void Toolbar::reconfigure() { + updateVisibleState(); if (!doAutoHide() && isHidden()) @@ -426,7 +431,8 @@ void Toolbar::reconfigure() { if (item == 0) continue; m_item_list.push_back(item); - item->resizeSig().attach(this); + // attach to first observer ( which must be rearrangeItems ) + item->resizeSig().attach(m_observers[0]); } // show all items @@ -515,6 +521,11 @@ void Toolbar::reconfigure() { // area to be reserved on screen updateStrut(); +#ifdef XINERAMA + if (m_xineramaheadmenu) + m_xineramaheadmenu->reloadHeads(); +#endif // XINERAMA + } @@ -613,22 +624,6 @@ void Toolbar::handleEvent(XEvent &event) { */ } -void Toolbar::update(FbTk::Subject *subj) { - - // either screen reconfigured, theme was reloaded - // or a tool resized itself - - if (typeid(*subj) == typeid(ToolbarItem::ToolbarItemSubject)) - rearrangeItems(); - else - reconfigure(); - -#ifdef XINERAMA - if (subj == &m_screen.resizeSig() && m_xineramaheadmenu) - m_xineramaheadmenu->reloadHeads(); -#endif // XINERAMA -} - void Toolbar::setPlacement(Toolbar::Placement where) { // disable vertical toolbar diff --git a/src/Toolbar.hh b/src/Toolbar.hh index c295e24..c68210f 100644 --- a/src/Toolbar.hh +++ b/src/Toolbar.hh @@ -37,7 +37,6 @@ #include "FbTk/Timer.hh" #include "FbTk/Resource.hh" -#include "FbTk/Observer.hh" #include "FbTk/XLayer.hh" #include "FbTk/XLayerItem.hh" #include "FbTk/EventHandler.hh" @@ -57,7 +56,8 @@ class Shape; /// The toolbar. /// Handles iconbar, workspace name view and clock view -class Toolbar: public FbTk::EventHandler, public FbTk::Observer, public LayerObject { +class Toolbar: public FbTk::EventHandler, + public LayerObject { public: /// Toolbar placement on the screen @@ -99,8 +99,6 @@ public: void reconfigure(); void setPlacement(Placement where); - void update(FbTk::Subject *subj); - int layerNumber() const { return const_cast(m_layeritem).getLayerNum(); } const FbTk::Menu &menu() const { return m_toolbarmenu; } @@ -193,6 +191,8 @@ private: StringList m_tools; bool m_resize_lock; ///< to lock rearrangeItems or not + /// observers for various signals + std::vector m_observers; }; -- cgit v0.11.2