all repos — fluxbox @ 80b10f7772b91f1f4a61eace4e5235a79060e1f0

custom fork of the fluxbox windowmanager

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.
Henrik Kinnunen fluxgen@fluxbox.org
commit

80b10f7772b91f1f4a61eace4e5235a79060e1f0

parent

40e17b4d0ef1b9503f21509e697dd4dcb24d2bbf

M src/FbTk/Makefile.amsrc/FbTk/Makefile.am

@@ -44,7 +44,7 @@ Resource.hh Resource.cc \

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 \
A 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 <typename Receiver> +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 <typename Receiver, typename Action> +Observer *makeObserver(Receiver &receiver, Action action) { + return new SimpleObserver<Receiver>( receiver, action ); +} + +} +
M src/SendToMenu.ccsrc/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 "Layer.hh"

#include "FbTk/MultiButtonMenuItem.hh" #include "FbTk/Command.hh" +#include "FbTk/SimpleObserver.hh" class SendToCmd: public FbTk::Command<void> { public:

@@ -54,24 +55,21 @@ // listen to:

// 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(); + // setup menu items + rebuildMenu(); +} - disableTitle(); - // build menu - update(0); +SendToMenu::~SendToMenu() { + delete m_rebuildObs; } -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; - } - - } +void SendToMenu::rebuildMenu() { // rebuild menu removeAll();

@@ -95,6 +93,7 @@ void SendToMenu::show() {

if (WindowCmd<void>::window() != 0) { for (unsigned int i=0; i < numberOfItems(); ++i) setItemEnabled(i, true); + // update the workspace for the current window setItemEnabled(WindowCmd<void>::window()->workspaceNumber(), false); updateMenu(); }
M src/SendToMenu.hhsrc/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 @@ #define SENDTOMENU_HH

#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
M src/SystemTray.ccsrc/SystemTray.cc

@@ -30,6 +30,7 @@ #include "fluxbox.hh"

#include "WinClient.hh" #include "Screen.hh" #include "ButtonTheme.hh" +#include "SimpleObserver.hh" #include <X11/Xutil.h> #include <X11/Xatom.h>

@@ -166,8 +167,10 @@ m_selection_owner(m_window, 0, 0, 1, 1, SubstructureNotifyMask, false, false, CopyFromParent, InputOnly) {

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 @@ ce.xclient.data.l[4] = 0l; // selection specific data

XSendEvent(disp, root_window, false, StructureNotifyMask, &ce); - update(0); + update(); } SystemTray::~SystemTray() {

@@ -276,7 +279,7 @@ }

void SystemTray::show() { - update(0); + update(); m_window.show(); }

@@ -470,7 +473,7 @@ FbTk::translateSize(orientation(), w_rot0, h_rot0);

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 @@ m_num_visible_clients++;

rearrangeClients(); } -void SystemTray::update(FbTk::Subject* subject) { +void SystemTray::update() { if (!m_theme->texture().usePixmap()) { m_window.setBackgroundColor(m_theme->texture().color());
M src/SystemTray.hhsrc/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 <list> +#include <memory> class BScreen; class ButtonTheme;

@@ -39,9 +39,10 @@ class AtomHandler;

namespace FbTk { template <class T> 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 @@ void renderTheme(unsigned char alpha) {

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 @@ static Atom getXEmbedInfoAtom();

private: - void update(FbTk::Subject *subj); + void update(); typedef std::list<TrayWindow *> ClientList; ClientList::iterator findClient(Window win);

@@ -108,7 +109,7 @@

// 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<FbTk::Observer> m_observer; }; #endif // SYSTEMTRAY_HH
M src/Toolbar.ccsrc/Toolbar.cc

@@ -50,7 +50,7 @@ #include "FbTk/Transparent.hh"

#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 @@ scrn.name() + ".toolbar.tools", scrn.altName() + ".Toolbar.Tools"),

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 @@ m_layeritem.lower();

} void Toolbar::reconfigure() { + updateVisibleState(); if (!doAutoHide() && isHidden())

@@ -426,7 +431,8 @@ ToolbarItem *item = m_tool_factory.create(*item_it, frame.window, *this);

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 @@ // we're done with all resizing and stuff now we can request a new

// area to be reserved on screen updateStrut(); +#ifdef XINERAMA + if (m_xineramaheadmenu) + m_xineramaheadmenu->reloadHeads(); +#endif // XINERAMA + }

@@ -611,22 +622,6 @@ event.xconfigure.window != window().window()) {

rearrangeItems(); } */ -} - -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) {
M src/Toolbar.hhsrc/Toolbar.hh

@@ -37,7 +37,6 @@ #endif // XINERAMA

#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 @@ }

/// 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

@@ -98,8 +98,6 @@ //@}

void reconfigure(); void setPlacement(Placement where); - - void update(FbTk::Subject *subj); int layerNumber() const { return const_cast<FbTk::XLayerItem &>(m_layeritem).getLayerNum(); }

@@ -193,6 +191,8 @@ typedef std::list<std::string> StringList;

StringList m_tools; bool m_resize_lock; ///< to lock rearrangeItems or not + /// observers for various signals + std::vector<FbTk::Observer*> m_observers; };