aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Kinnunen <fluxgen@fluxbox.org>2008-04-27 19:22:18 (GMT)
committerHenrik Kinnunen <fluxgen@fluxbox.org>2008-04-27 19:22:18 (GMT)
commit80b10f7772b91f1f4a61eace4e5235a79060e1f0 (patch)
tree27057e59c41188e7c2f724614233265fed03c9b3
parent40e17b4d0ef1b9503f21509e697dd4dcb24d2bbf (diff)
downloadfluxbox-80b10f7772b91f1f4a61eace4e5235a79060e1f0.zip
fluxbox-80b10f7772b91f1f4a61eace4e5235a79060e1f0.tar.bz2
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.
-rw-r--r--src/FbTk/Makefile.am2
-rw-r--r--src/FbTk/SimpleObserver.hh70
-rw-r--r--src/SendToMenu.cc31
-rw-r--r--src/SendToMenu.hh23
-rw-r--r--src/SystemTray.cc15
-rw-r--r--src/SystemTray.hh11
-rw-r--r--src/Toolbar.cc37
-rw-r--r--src/Toolbar.hh8
8 files changed, 139 insertions, 58 deletions
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 \
44 StringUtil.hh StringUtil.cc Parser.hh Parser.cc \ 44 StringUtil.hh StringUtil.cc Parser.hh Parser.cc \
45 RegExp.hh RegExp.cc \ 45 RegExp.hh RegExp.cc \
46 FbString.hh FbString.cc \ 46 FbString.hh FbString.cc \
47 Subject.hh Subject.cc Observer.hh Observer.cc \ 47 Subject.hh Subject.cc Observer.hh Observer.cc SimpleObserver.hh \
48 Transparent.hh Transparent.cc \ 48 Transparent.hh Transparent.cc \
49 FbPixmap.hh FbPixmap.cc \ 49 FbPixmap.hh FbPixmap.cc \
50 FbDrawable.hh FbDrawable.cc \ 50 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 @@
1// SimpleObserver.hh
2// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22#include "Observer.hh"
23#include "SimpleCommand.hh"
24
25namespace FbTk {
26
27/** Functor for observers, instead of using this directly use makeObserver.
28 * Usage:
29 * @code
30 * class SomeClass {
31 * public:
32 * void doAction();
33 * };
34 *
35 * SomeClass some;
36 *
37 * Observer* obs = makeProxyObserver(some, &SomeClass::doAction);
38 * SomeSubject subj;
39 * subj.attach(obs);
40 * @endcode
41 */
42template <typename Receiver>
43class SimpleObserver: public Observer {
44public:
45 typedef void (Receiver::* Action)();
46 SimpleObserver(Receiver &r, Action a):
47 m_receiver(r), m_action(a) {
48
49 }
50 void update(Subject *changedSubj) {
51 (m_receiver.*m_action)();
52 }
53private:
54 Receiver &m_receiver;
55 Action m_action;
56};
57
58// Helpers
59/** Creates an observer that takes no arguments.
60 * @param receiver The receiving instance.
61 * @param action A function in the receiving class.
62 * @return allocated simple observer. @see SimpleObserver
63 */
64template <typename Receiver, typename Action>
65Observer *makeObserver(Receiver &receiver, Action action) {
66 return new SimpleObserver<Receiver>( receiver, action );
67}
68
69}
70
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 @@
1// SendToMenu.cc for Fluxbox 1// SendToMenu.cc for Fluxbox
2// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org) 2// Copyright (c) 2003 - 2008 Henrik Kinnunen (fluxgen at fluxbox dot org)
3// and Simon Bowden (rathnor at users.sourceforge.net) 3// and Simon Bowden (rathnor at users.sourceforge.net)
4// 4//
5// Permission is hereby granted, free of charge, to any person obtaining a 5// Permission is hereby granted, free of charge, to any person obtaining a
@@ -31,6 +31,7 @@
31 31
32#include "FbTk/MultiButtonMenuItem.hh" 32#include "FbTk/MultiButtonMenuItem.hh"
33#include "FbTk/Command.hh" 33#include "FbTk/Command.hh"
34#include "FbTk/SimpleObserver.hh"
34 35
35class SendToCmd: public FbTk::Command<void> { 36class SendToCmd: public FbTk::Command<void> {
36public: 37public:
@@ -54,24 +55,21 @@ SendToMenu::SendToMenu(BScreen &screen):
54 // workspace count signal 55 // workspace count signal
55 // workspace names signal 56 // workspace names signal
56 // current workspace signal 57 // current workspace signal
57 screen.workspaceCountSig().attach(this); 58 m_rebuildObs = makeObserver(*this, &SendToMenu::rebuildMenu);
58 screen.workspaceNamesSig().attach(this); 59 screen.workspaceCountSig().attach(m_rebuildObs);
59 screen.currentWorkspaceSig().attach(this); 60 screen.workspaceNamesSig().attach(m_rebuildObs);
60 61 screen.currentWorkspaceSig().attach(m_rebuildObs);
62 // no title for this menu, it should be a submenu in the window menu.
61 disableTitle(); 63 disableTitle();
62 // build menu 64 // setup menu items
63 update(0); 65 rebuildMenu();
64} 66}
65 67
66void SendToMenu::update(FbTk::Subject *subj) { 68SendToMenu::~SendToMenu() {
67 if (subj != 0) { 69 delete m_rebuildObs;
68 if (subj == &(theme().reconfigSig())) { 70}
69 // we got reconfig Theme signal, let base menu handle it 71
70 FbTk::Menu::update(subj); 72void SendToMenu::rebuildMenu() {
71 return;
72 }
73
74 }
75 // rebuild menu 73 // rebuild menu
76 74
77 removeAll(); 75 removeAll();
@@ -95,6 +93,7 @@ void SendToMenu::show() {
95 if (WindowCmd<void>::window() != 0) { 93 if (WindowCmd<void>::window() != 0) {
96 for (unsigned int i=0; i < numberOfItems(); ++i) 94 for (unsigned int i=0; i < numberOfItems(); ++i)
97 setItemEnabled(i, true); 95 setItemEnabled(i, true);
96 // update the workspace for the current window
98 setItemEnabled(WindowCmd<void>::window()->workspaceNumber(), false); 97 setItemEnabled(WindowCmd<void>::window()->workspaceNumber(), false);
99 updateMenu(); 98 updateMenu();
100 } 99 }
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 @@
1// SendToMenu.hh for Fluxbox 1// SendToMenu.hh for Fluxbox
2// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org) 2// Copyright (c) 2003 - 2008 Henrik Kinnunen (fluxgen at fluxbox dot org)
3// and Simon Bowden (rathnor at users.sourceforge.net) 3// and Simon Bowden (rathnor at users.sourceforge.net)
4// 4//
5// Permission is hereby granted, free of charge, to any person obtaining a 5// Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,15 +25,28 @@
25 25
26#include "FbMenu.hh" 26#include "FbMenu.hh"
27 27
28namespace FbTk {
29class Observer;
30}
31
28class BScreen; 32class BScreen;
29 33
34/**
35 * Creates the "send to menu".
36 * Displays all the workspaces for which the current window can be sent to.
37 */
30class SendToMenu:public FbMenu { 38class SendToMenu:public FbMenu {
31public: 39public:
32 explicit SendToMenu(BScreen &win); 40 /// @param screen the screen on which this menu should be created on.
33 virtual ~SendToMenu() { } 41 explicit SendToMenu(BScreen &screen);
42 virtual ~SendToMenu();
43 /// @see FbTk::Menu
34 void show(); 44 void show();
35protected: 45private:
36 void update(FbTk::Subject *subj); 46 /// Rebuild the menu from scratch.
47 void rebuildMenu();
48 /// listens to signals that makes this instance need to rebuild menu
49 FbTk::Observer *m_rebuildObs;
37}; 50};
38 51
39#endif // SENDTOMENU_HH 52#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 @@
30#include "WinClient.hh" 30#include "WinClient.hh"
31#include "Screen.hh" 31#include "Screen.hh"
32#include "ButtonTheme.hh" 32#include "ButtonTheme.hh"
33#include "SimpleObserver.hh"
33 34
34#include <X11/Xutil.h> 35#include <X11/Xutil.h>
35#include <X11/Xatom.h> 36#include <X11/Xatom.h>
@@ -166,8 +167,10 @@ SystemTray::SystemTray(const FbTk::FbWindow& parent,
166 167
167 FbTk::EventManager::instance()->add(*this, m_window); 168 FbTk::EventManager::instance()->add(*this, m_window);
168 FbTk::EventManager::instance()->add(*this, m_selection_owner); 169 FbTk::EventManager::instance()->add(*this, m_selection_owner);
169 m_theme->reconfigSig().attach(this); 170 // setup signals
170 screen.bgChangeSig().attach(this); 171 m_observer.reset(makeObserver(*this, &SystemTray::update));
172 m_theme->reconfigSig().attach(m_observer.get());
173 screen.bgChangeSig().attach(m_observer.get());
171 174
172 Fluxbox* fluxbox = Fluxbox::instance(); 175 Fluxbox* fluxbox = Fluxbox::instance();
173 Display *disp = fluxbox->display(); 176 Display *disp = fluxbox->display();
@@ -216,7 +219,7 @@ SystemTray::SystemTray(const FbTk::FbWindow& parent,
216 219
217 XSendEvent(disp, root_window, false, StructureNotifyMask, &ce); 220 XSendEvent(disp, root_window, false, StructureNotifyMask, &ce);
218 221
219 update(0); 222 update();
220} 223}
221 224
222SystemTray::~SystemTray() { 225SystemTray::~SystemTray() {
@@ -276,7 +279,7 @@ void SystemTray::hide() {
276 279
277void SystemTray::show() { 280void SystemTray::show() {
278 281
279 update(0); 282 update();
280 m_window.show(); 283 m_window.show();
281} 284}
282 285
@@ -470,7 +473,7 @@ void SystemTray::rearrangeClients() {
470 unsigned int trayw = m_num_visible_clients*h_rot0 + bw, trayh = h_rot0; 473 unsigned int trayw = m_num_visible_clients*h_rot0 + bw, trayh = h_rot0;
471 FbTk::translateSize(orientation(), trayw, trayh); 474 FbTk::translateSize(orientation(), trayw, trayh);
472 resize(trayw, trayh); 475 resize(trayw, trayh);
473 update(0); 476 update();
474 477
475 // move and resize clients 478 // move and resize clients
476 ClientList::iterator client_it = m_clients.begin(); 479 ClientList::iterator client_it = m_clients.begin();
@@ -529,7 +532,7 @@ void SystemTray::showClient(TrayWindow *traywin) {
529 rearrangeClients(); 532 rearrangeClients();
530} 533}
531 534
532void SystemTray::update(FbTk::Subject* subject) { 535void SystemTray::update() {
533 536
534 if (!m_theme->texture().usePixmap()) { 537 if (!m_theme->texture().usePixmap()) {
535 m_window.setBackgroundColor(m_theme->texture().color()); 538 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 @@
25 25
26#include "FbTk/FbWindow.hh" 26#include "FbTk/FbWindow.hh"
27#include "FbTk/EventHandler.hh" 27#include "FbTk/EventHandler.hh"
28#include "FbTk/Observer.hh"
29 28
30#include "ToolTheme.hh" 29#include "ToolTheme.hh"
31#include "ToolbarItem.hh" 30#include "ToolbarItem.hh"
32 31
33#include <list> 32#include <list>
33#include <memory>
34 34
35class BScreen; 35class BScreen;
36class ButtonTheme; 36class ButtonTheme;
@@ -39,9 +39,10 @@ class AtomHandler;
39 39
40namespace FbTk { 40namespace FbTk {
41template <class T> class ThemeProxy; 41template <class T> class ThemeProxy;
42class Observer;
42} 43}
43 44
44class SystemTray: public ToolbarItem, public FbTk::EventHandler, public FbTk::Observer { 45class SystemTray: public ToolbarItem, public FbTk::EventHandler {
45public: 46public:
46 47
47 explicit SystemTray(const FbTk::FbWindow &parent, 48 explicit SystemTray(const FbTk::FbWindow &parent,
@@ -75,7 +76,7 @@ public:
75 m_window.setBorderWidth(m_theme->border().width()); 76 m_window.setBorderWidth(m_theme->border().width());
76 m_window.setBorderColor(m_theme->border().color()); 77 m_window.setBorderColor(m_theme->border().color());
77 m_window.setAlpha(alpha); 78 m_window.setAlpha(alpha);
78 update(0); 79 update();
79 } 80 }
80 void updateSizing() { m_window.setBorderWidth(m_theme->border().width()); } 81 void updateSizing() { m_window.setBorderWidth(m_theme->border().width()); }
81 82
@@ -85,7 +86,7 @@ public:
85 86
86private: 87private:
87 88
88 void update(FbTk::Subject *subj); 89 void update();
89 90
90 typedef std::list<TrayWindow *> ClientList; 91 typedef std::list<TrayWindow *> ClientList;
91 ClientList::iterator findClient(Window win); 92 ClientList::iterator findClient(Window win);
@@ -108,7 +109,7 @@ private:
108 // gaim/pidgin seems to barf if the selection is not an independent window. 109 // gaim/pidgin seems to barf if the selection is not an independent window.
109 // I suspect it's an interacton with parent relationship and gdk window caching. 110 // I suspect it's an interacton with parent relationship and gdk window caching.
110 FbTk::FbWindow m_selection_owner; 111 FbTk::FbWindow m_selection_owner;
111 112 std::auto_ptr<FbTk::Observer> m_observer;
112}; 113};
113 114
114#endif // SYSTEMTRAY_HH 115#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 @@
50#include "FbTk/BoolMenuItem.hh" 50#include "FbTk/BoolMenuItem.hh"
51#include "FbTk/IntMenuItem.hh" 51#include "FbTk/IntMenuItem.hh"
52#include "FbTk/Shape.hh" 52#include "FbTk/Shape.hh"
53 53#include "FbTk/SimpleObserver.hh"
54 54
55// use GNU extensions 55// use GNU extensions
56#ifndef _GNU_SOURCE 56#ifndef _GNU_SOURCE
@@ -240,11 +240,15 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, size_t width):
240 m_shape(new FbTk::Shape(frame.window, 0)), 240 m_shape(new FbTk::Shape(frame.window, 0)),
241 m_resize_lock(false) { 241 m_resize_lock(false) {
242 _FB_USES_NLS; 242 _FB_USES_NLS;
243 // NOTE: first subject is always the rearrangeItem !
244 m_observers.push_back(makeObserver(*this, &Toolbar::rearrangeItems));
243 // we need to get notified when the theme is reloaded 245 // we need to get notified when the theme is reloaded
244 m_theme.reconfigSig().attach(this); 246 m_observers.push_back(makeObserver(*this, &Toolbar::reconfigure));
247 m_theme.reconfigSig().attach(m_observers.back());
248 screen().reconfigureSig().attach(m_observers.back()); // get this on antialias change
245 // listen to screen size changes 249 // listen to screen size changes
246 screen().resizeSig().attach(this); 250 screen().resizeSig().attach(m_observers.back());
247 screen().reconfigureSig().attach(this); // get this on antialias change 251
248 252
249 moveToLayer((*m_rc_layernum).getNum()); 253 moveToLayer((*m_rc_layernum).getNum());
250 254
@@ -370,6 +374,7 @@ void Toolbar::lower() {
370} 374}
371 375
372void Toolbar::reconfigure() { 376void Toolbar::reconfigure() {
377
373 updateVisibleState(); 378 updateVisibleState();
374 379
375 if (!doAutoHide() && isHidden()) 380 if (!doAutoHide() && isHidden())
@@ -426,7 +431,8 @@ void Toolbar::reconfigure() {
426 if (item == 0) 431 if (item == 0)
427 continue; 432 continue;
428 m_item_list.push_back(item); 433 m_item_list.push_back(item);
429 item->resizeSig().attach(this); 434 // attach to first observer ( which must be rearrangeItems )
435 item->resizeSig().attach(m_observers[0]);
430 436
431 } 437 }
432 // show all items 438 // show all items
@@ -515,6 +521,11 @@ void Toolbar::reconfigure() {
515 // area to be reserved on screen 521 // area to be reserved on screen
516 updateStrut(); 522 updateStrut();
517 523
524#ifdef XINERAMA
525 if (m_xineramaheadmenu)
526 m_xineramaheadmenu->reloadHeads();
527#endif // XINERAMA
528
518} 529}
519 530
520 531
@@ -613,22 +624,6 @@ void Toolbar::handleEvent(XEvent &event) {
613*/ 624*/
614} 625}
615 626
616void Toolbar::update(FbTk::Subject *subj) {
617
618 // either screen reconfigured, theme was reloaded
619 // or a tool resized itself
620
621 if (typeid(*subj) == typeid(ToolbarItem::ToolbarItemSubject))
622 rearrangeItems();
623 else
624 reconfigure();
625
626#ifdef XINERAMA
627 if (subj == &m_screen.resizeSig() && m_xineramaheadmenu)
628 m_xineramaheadmenu->reloadHeads();
629#endif // XINERAMA
630}
631
632void Toolbar::setPlacement(Toolbar::Placement where) { 627void Toolbar::setPlacement(Toolbar::Placement where) {
633 // disable vertical toolbar 628 // disable vertical toolbar
634 629
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 @@
37 37
38#include "FbTk/Timer.hh" 38#include "FbTk/Timer.hh"
39#include "FbTk/Resource.hh" 39#include "FbTk/Resource.hh"
40#include "FbTk/Observer.hh"
41#include "FbTk/XLayer.hh" 40#include "FbTk/XLayer.hh"
42#include "FbTk/XLayerItem.hh" 41#include "FbTk/XLayerItem.hh"
43#include "FbTk/EventHandler.hh" 42#include "FbTk/EventHandler.hh"
@@ -57,7 +56,8 @@ class Shape;
57 56
58/// The toolbar. 57/// The toolbar.
59/// Handles iconbar, workspace name view and clock view 58/// Handles iconbar, workspace name view and clock view
60class Toolbar: public FbTk::EventHandler, public FbTk::Observer, public LayerObject { 59class Toolbar: public FbTk::EventHandler,
60 public LayerObject {
61public: 61public:
62 62
63 /// Toolbar placement on the screen 63 /// Toolbar placement on the screen
@@ -99,8 +99,6 @@ public:
99 void reconfigure(); 99 void reconfigure();
100 void setPlacement(Placement where); 100 void setPlacement(Placement where);
101 101
102 void update(FbTk::Subject *subj);
103
104 int layerNumber() const { return const_cast<FbTk::XLayerItem &>(m_layeritem).getLayerNum(); } 102 int layerNumber() const { return const_cast<FbTk::XLayerItem &>(m_layeritem).getLayerNum(); }
105 103
106 const FbTk::Menu &menu() const { return m_toolbarmenu; } 104 const FbTk::Menu &menu() const { return m_toolbarmenu; }
@@ -193,6 +191,8 @@ private:
193 StringList m_tools; 191 StringList m_tools;
194 192
195 bool m_resize_lock; ///< to lock rearrangeItems or not 193 bool m_resize_lock; ///< to lock rearrangeItems or not
194 /// observers for various signals
195 std::vector<FbTk::Observer*> m_observers;
196}; 196};
197 197
198 198