diff options
-rw-r--r-- | src/SystemTray.cc | 93 | ||||
-rw-r--r-- | src/SystemTray.hh | 15 | ||||
-rw-r--r-- | src/ToolFactory.cc | 9 | ||||
-rw-r--r-- | src/ToolFactory.hh | 4 |
4 files changed, 91 insertions, 30 deletions
diff --git a/src/SystemTray.cc b/src/SystemTray.cc index ab64f20..c4b9331 100644 --- a/src/SystemTray.cc +++ b/src/SystemTray.cc | |||
@@ -1,5 +1,5 @@ | |||
1 | // SystemTray.cc | 1 | // SystemTray.cc |
2 | // Copyright (c) 2003-2004 Henrik Kinnunen (fluxgen at users.sourceforge.net) | 2 | // Copyright (c) 2003-2005 Henrik Kinnunen (fluxgen at users.sourceforge.net) |
3 | // | 3 | // |
4 | // Permission is hereby granted, free of charge, to any person obtaining a | 4 | // Permission is hereby granted, free of charge, to any person obtaining a |
5 | // copy of this software and associated documentation files (the "Software"), | 5 | // copy of this software and associated documentation files (the "Software"), |
@@ -24,6 +24,7 @@ | |||
24 | #include "SystemTray.hh" | 24 | #include "SystemTray.hh" |
25 | 25 | ||
26 | #include "FbTk/EventManager.hh" | 26 | #include "FbTk/EventManager.hh" |
27 | #include "FbTk/ImageControl.hh" | ||
27 | 28 | ||
28 | #include "AtomHandler.hh" | 29 | #include "AtomHandler.hh" |
29 | #include "fluxbox.hh" | 30 | #include "fluxbox.hh" |
@@ -49,7 +50,7 @@ public: | |||
49 | SystemTrayHandler(SystemTray &tray):m_tray(tray) { | 50 | SystemTrayHandler(SystemTray &tray):m_tray(tray) { |
50 | } | 51 | } |
51 | // client message is the only thing we care about | 52 | // client message is the only thing we care about |
52 | bool checkClientMessage(const XClientMessageEvent &ce, | 53 | bool checkClientMessage(const XClientMessageEvent &ce, |
53 | BScreen * screen, WinClient * const winclient) { | 54 | BScreen * screen, WinClient * const winclient) { |
54 | // must be on the same screen | 55 | // must be on the same screen |
55 | if ((screen && screen->screenNumber() != m_tray.window().screenNumber()) || | 56 | if ((screen && screen->screenNumber() != m_tray.window().screenNumber()) || |
@@ -60,11 +61,11 @@ public: | |||
60 | 61 | ||
61 | void initForScreen(BScreen &screen) { }; | 62 | void initForScreen(BScreen &screen) { }; |
62 | void setupFrame(FluxboxWindow &win) { }; | 63 | void setupFrame(FluxboxWindow &win) { }; |
63 | void setupClient(WinClient &winclient) { | 64 | void setupClient(WinClient &winclient) { |
64 | // must be on the same screen | 65 | // must be on the same screen |
65 | if (winclient.screenNumber() != m_tray.window().screenNumber()) | 66 | if (winclient.screenNumber() != m_tray.window().screenNumber()) |
66 | return; | 67 | return; |
67 | 68 | ||
68 | // we dont want a managed window | 69 | // we dont want a managed window |
69 | if (winclient.fbwindow() != 0) | 70 | if (winclient.fbwindow() != 0) |
70 | return; | 71 | return; |
@@ -100,15 +101,19 @@ private: | |||
100 | SystemTray &m_tray; | 101 | SystemTray &m_tray; |
101 | }; | 102 | }; |
102 | 103 | ||
103 | SystemTray::SystemTray(const FbTk::FbWindow &parent): | 104 | SystemTray::SystemTray(const FbTk::FbWindow& parent, ButtonTheme& theme, BScreen& screen): |
104 | ToolbarItem(ToolbarItem::FIXED), | 105 | ToolbarItem(ToolbarItem::FIXED), |
105 | m_window(parent, 0, 0, 1, 1, ExposureMask | ButtonPressMask | ButtonReleaseMask | | 106 | m_window(parent, 0, 0, 1, 1, ExposureMask | ButtonPressMask | ButtonReleaseMask | |
106 | SubstructureNotifyMask | SubstructureRedirectMask) { | 107 | SubstructureNotifyMask | SubstructureRedirectMask), |
108 | m_theme(theme), | ||
109 | m_screen(screen), | ||
110 | m_pixmap(0) { | ||
107 | 111 | ||
108 | FbTk::EventManager::instance()->add(*this, m_window); | 112 | FbTk::EventManager::instance()->add(*this, m_window); |
113 | m_theme.reconfigSig().attach(this); | ||
109 | 114 | ||
110 | // just try to blend in... (better than defaulting to white) | 115 | Fluxbox* fluxbox = Fluxbox::instance(); |
111 | m_window.setBackgroundPixmap(ParentRelative); | 116 | Display *disp = fluxbox->display(); |
112 | 117 | ||
113 | // setup atom name to _NET_SYSTEM_TRAY_S<screen number> | 118 | // setup atom name to _NET_SYSTEM_TRAY_S<screen number> |
114 | char intbuff[16]; | 119 | char intbuff[16]; |
@@ -116,8 +121,6 @@ SystemTray::SystemTray(const FbTk::FbWindow &parent): | |||
116 | std::string atom_name("_NET_SYSTEM_TRAY_S"); | 121 | std::string atom_name("_NET_SYSTEM_TRAY_S"); |
117 | atom_name += intbuff; // append number | 122 | atom_name += intbuff; // append number |
118 | 123 | ||
119 | Display *disp = FbTk::App::instance()->display(); | ||
120 | |||
121 | // get selection owner and see if it's free | 124 | // get selection owner and see if it's free |
122 | Atom tray_atom = XInternAtom(disp, atom_name.c_str(), False); | 125 | Atom tray_atom = XInternAtom(disp, atom_name.c_str(), False); |
123 | Window owner = XGetSelectionOwner(disp, tray_atom); | 126 | Window owner = XGetSelectionOwner(disp, tray_atom); |
@@ -134,11 +137,14 @@ SystemTray::SystemTray(const FbTk::FbWindow &parent): | |||
134 | #endif // DEBUG | 137 | #endif // DEBUG |
135 | // set owner | 138 | // set owner |
136 | XSetSelectionOwner(disp, tray_atom, m_window.window(), CurrentTime); | 139 | XSetSelectionOwner(disp, tray_atom, m_window.window(), CurrentTime); |
140 | |||
137 | m_handler.reset(new SystemTrayHandler(*this)); | 141 | m_handler.reset(new SystemTrayHandler(*this)); |
138 | Fluxbox::instance()->addAtomHandler(m_handler.get(), atom_name); | 142 | |
139 | Window root_window = RootWindow(disp, m_window.screenNumber()); | 143 | fluxbox->addAtomHandler(m_handler.get(), atom_name); |
144 | |||
140 | 145 | ||
141 | // send selection owner msg | 146 | // send selection owner msg |
147 | Window root_window = m_screen.rootWindow().window(); | ||
142 | XEvent ce; | 148 | XEvent ce; |
143 | ce.xclient.type = ClientMessage; | 149 | ce.xclient.type = ClientMessage; |
144 | ce.xclient.message_type = XInternAtom(disp, "MANAGER", False); | 150 | ce.xclient.message_type = XInternAtom(disp, "MANAGER", False); |
@@ -153,12 +159,17 @@ SystemTray::SystemTray(const FbTk::FbWindow &parent): | |||
153 | 159 | ||
154 | XSendEvent(disp, root_window, false, StructureNotifyMask, &ce); | 160 | XSendEvent(disp, root_window, false, StructureNotifyMask, &ce); |
155 | 161 | ||
162 | update(0); | ||
156 | } | 163 | } |
157 | 164 | ||
158 | SystemTray::~SystemTray() { | 165 | SystemTray::~SystemTray() { |
159 | // remove us, else fluxbox might delete the memory too | 166 | // remove us, else fluxbox might delete the memory too |
160 | Fluxbox::instance()->removeAtomHandler(m_handler.get()); | 167 | Fluxbox::instance()->removeAtomHandler(m_handler.get()); |
161 | removeAllClients(); | 168 | removeAllClients(); |
169 | |||
170 | if (m_pixmap) | ||
171 | m_screen.imageControl().removeImage(m_pixmap); | ||
172 | |||
162 | // ~FbWindow cleans EventManager | 173 | // ~FbWindow cleans EventManager |
163 | } | 174 | } |
164 | 175 | ||
@@ -196,11 +207,13 @@ void SystemTray::hide() { | |||
196 | } | 207 | } |
197 | 208 | ||
198 | void SystemTray::show() { | 209 | void SystemTray::show() { |
210 | |||
211 | update(0); | ||
199 | m_window.show(); | 212 | m_window.show(); |
200 | } | 213 | } |
201 | 214 | ||
202 | unsigned int SystemTray::width() const { | 215 | unsigned int SystemTray::width() const { |
203 | return m_clients.size()*height(); | 216 | return m_clients.size()* (height() - 2 * m_theme.border().width()); |
204 | } | 217 | } |
205 | 218 | ||
206 | unsigned int SystemTray::height() const { | 219 | unsigned int SystemTray::height() const { |
@@ -216,7 +229,7 @@ bool SystemTray::clientMessage(const XClientMessageEvent &event) { | |||
216 | // static const int SYSTEM_TRAY_BEGIN_MESSAGE = 1; | 229 | // static const int SYSTEM_TRAY_BEGIN_MESSAGE = 1; |
217 | // static const int SYSTEM_TRAY_CANCEL_MESSAGE = 2; | 230 | // static const int SYSTEM_TRAY_CANCEL_MESSAGE = 2; |
218 | 231 | ||
219 | if (event.message_type == | 232 | if (event.message_type == |
220 | XInternAtom(FbTk::App::instance()->display(), "_NET_SYSTEM_TRAY_OPCODE", False)) { | 233 | XInternAtom(FbTk::App::instance()->display(), "_NET_SYSTEM_TRAY_OPCODE", False)) { |
221 | 234 | ||
222 | int type = event.data.l[1]; | 235 | int type = event.data.l[1]; |
@@ -264,8 +277,8 @@ void SystemTray::addClient(Window win) { | |||
264 | XWindowAttributes attr; | 277 | XWindowAttributes attr; |
265 | attr.screen = 0; | 278 | attr.screen = 0; |
266 | if (XGetWindowAttributes(FbTk::App::instance()->display(), | 279 | if (XGetWindowAttributes(FbTk::App::instance()->display(), |
267 | win, &attr) != 0 && | 280 | win, &attr) != 0 && |
268 | attr.screen != 0 && | 281 | attr.screen != 0 && |
269 | XScreenNumberOfScreen(attr.screen) != window().screenNumber()) { | 282 | XScreenNumberOfScreen(attr.screen) != window().screenNumber()) { |
270 | return; | 283 | return; |
271 | } | 284 | } |
@@ -313,12 +326,13 @@ void SystemTray::removeClient(Window win) { | |||
313 | 326 | ||
314 | void SystemTray::exposeEvent(XExposeEvent &event) { | 327 | void SystemTray::exposeEvent(XExposeEvent &event) { |
315 | m_window.clear(); | 328 | m_window.clear(); |
329 | update(0); | ||
316 | } | 330 | } |
317 | 331 | ||
318 | void SystemTray::handleEvent(XEvent &event) { | 332 | void SystemTray::handleEvent(XEvent &event) { |
319 | if (event.type == DestroyNotify) { | 333 | if (event.type == DestroyNotify) { |
320 | removeClient(event.xdestroywindow.window); | 334 | removeClient(event.xdestroywindow.window); |
321 | } else if (event.type == UnmapNotify && event.xany.send_event) { | 335 | } else if (event.type == UnmapNotify && event.xany.send_event) { |
322 | // we ignore server-generated events, which can occur | 336 | // we ignore server-generated events, which can occur |
323 | // on restart. The ICCCM says that a client must send | 337 | // on restart. The ICCCM says that a client must send |
324 | // a synthetic event for the withdrawn state | 338 | // a synthetic event for the withdrawn state |
@@ -326,7 +340,7 @@ void SystemTray::handleEvent(XEvent &event) { | |||
326 | } else if (event.type == ConfigureNotify) { | 340 | } else if (event.type == ConfigureNotify) { |
327 | // we got configurenotify from an client | 341 | // we got configurenotify from an client |
328 | // check and see if we need to update it's size | 342 | // check and see if we need to update it's size |
329 | // and we must reposition and resize them to fit | 343 | // and we must reposition and resize them to fit |
330 | // our toolbar | 344 | // our toolbar |
331 | ClientList::iterator it = findClient(event.xconfigure.window); | 345 | ClientList::iterator it = findClient(event.xconfigure.window); |
332 | if (it != m_clients.end()) { | 346 | if (it != m_clients.end()) { |
@@ -345,15 +359,19 @@ void SystemTray::handleEvent(XEvent &event) { | |||
345 | } | 359 | } |
346 | 360 | ||
347 | void SystemTray::rearrangeClients() { | 361 | void SystemTray::rearrangeClients() { |
348 | // move and resize clients | 362 | // move and resize clients |
349 | ClientList::iterator client_it = m_clients.begin(); | 363 | ClientList::iterator client_it = m_clients.begin(); |
350 | ClientList::iterator client_it_end = m_clients.end(); | 364 | ClientList::iterator client_it_end = m_clients.end(); |
351 | int next_x = 0; | 365 | int next_x = 0; |
352 | for (; client_it != client_it_end; ++client_it, next_x += height()) { | 366 | const unsigned int h = height(); |
353 | (*client_it)->moveResize(next_x, 0, height(), height()); | 367 | const unsigned int b = m_theme.border().width(); |
368 | for (; client_it != client_it_end; | ||
369 | ++client_it, next_x += h - 2 * b) { | ||
370 | (*client_it)->moveResize(next_x, b, h - b, h - b); | ||
354 | } | 371 | } |
355 | 372 | ||
356 | resize(next_x, height()); | 373 | resize(next_x, height()); |
374 | update(0); | ||
357 | } | 375 | } |
358 | 376 | ||
359 | void SystemTray::removeAllClients() { | 377 | void SystemTray::removeAllClients() { |
@@ -366,3 +384,34 @@ void SystemTray::removeAllClients() { | |||
366 | m_clients.pop_back(); | 384 | m_clients.pop_back(); |
367 | } | 385 | } |
368 | } | 386 | } |
387 | |||
388 | void SystemTray::update(FbTk::Subject* subject) { | ||
389 | |||
390 | if (!m_theme.texture().usePixmap()) { | ||
391 | m_window.setBackgroundColor(m_theme.texture().color()); | ||
392 | } | ||
393 | else { | ||
394 | if(m_pixmap) | ||
395 | m_screen.imageControl().removeImage(m_pixmap); | ||
396 | m_pixmap = m_screen.imageControl().renderImage(width(), height(), | ||
397 | m_theme.texture()); | ||
398 | m_window.setBackgroundPixmap(m_pixmap); | ||
399 | } | ||
400 | |||
401 | // "themereconfigure" | ||
402 | if (subject) { | ||
403 | ClientList::iterator client_it = m_clients.begin(); | ||
404 | ClientList::iterator client_it_end = m_clients.end(); | ||
405 | int next_x = 0; | ||
406 | const unsigned int h = height(); | ||
407 | const unsigned int b = m_theme.border().width(); | ||
408 | for (; client_it != client_it_end; | ||
409 | ++client_it, next_x += h - 2 * b) { | ||
410 | |||
411 | // maybe not the best solution (yet), force a refresh of the | ||
412 | // background of the client | ||
413 | (*client_it)->hide(); | ||
414 | (*client_it)->show(); | ||
415 | } | ||
416 | } | ||
417 | } | ||
diff --git a/src/SystemTray.hh b/src/SystemTray.hh index cceb434..f165856 100644 --- a/src/SystemTray.hh +++ b/src/SystemTray.hh | |||
@@ -1,5 +1,5 @@ | |||
1 | // SystemTray.hh | 1 | // SystemTray.hh |
2 | // Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net) | 2 | // Copyright (c) 2003-2005 Henrik Kinnunen (fluxgen at users.sourceforge.net) |
3 | // | 3 | // |
4 | // Permission is hereby granted, free of charge, to any person obtaining a | 4 | // Permission is hereby granted, free of charge, to any person obtaining a |
5 | // copy of this software and associated documentation files (the "Software"), | 5 | // copy of this software and associated documentation files (the "Software"), |
@@ -27,8 +27,11 @@ | |||
27 | 27 | ||
28 | #include "FbTk/FbWindow.hh" | 28 | #include "FbTk/FbWindow.hh" |
29 | #include "FbTk/EventHandler.hh" | 29 | #include "FbTk/EventHandler.hh" |
30 | #include "FbTk/Observer.hh" | ||
30 | 31 | ||
31 | #include "ToolbarItem.hh" | 32 | #include "ToolbarItem.hh" |
33 | #include "ButtonTheme.hh" | ||
34 | #include "Screen.hh" | ||
32 | 35 | ||
33 | #include <X11/Xlib.h> | 36 | #include <X11/Xlib.h> |
34 | 37 | ||
@@ -36,10 +39,10 @@ | |||
36 | 39 | ||
37 | class AtomHandler; | 40 | class AtomHandler; |
38 | 41 | ||
39 | class SystemTray: public ToolbarItem, public FbTk::EventHandler { | 42 | class SystemTray: public ToolbarItem, public FbTk::EventHandler, public FbTk::Observer { |
40 | public: | 43 | public: |
41 | 44 | ||
42 | explicit SystemTray(const FbTk::FbWindow &parent); | 45 | explicit SystemTray(const FbTk::FbWindow &parent, ButtonTheme &theme, BScreen& screen); |
43 | virtual ~SystemTray(); | 46 | virtual ~SystemTray(); |
44 | 47 | ||
45 | void move(int x, int y); | 48 | void move(int x, int y); |
@@ -69,6 +72,9 @@ public: | |||
69 | inline void updateSizing() {} | 72 | inline void updateSizing() {} |
70 | 73 | ||
71 | private: | 74 | private: |
75 | |||
76 | void update(FbTk::Subject *subj); | ||
77 | |||
72 | typedef std::list<FbTk::FbWindow *> ClientList; | 78 | typedef std::list<FbTk::FbWindow *> ClientList; |
73 | ClientList::iterator findClient(Window win); | 79 | ClientList::iterator findClient(Window win); |
74 | 80 | ||
@@ -76,6 +82,9 @@ private: | |||
76 | void removeAllClients(); | 82 | void removeAllClients(); |
77 | 83 | ||
78 | FbTk::FbWindow m_window; | 84 | FbTk::FbWindow m_window; |
85 | ButtonTheme& m_theme; | ||
86 | BScreen& m_screen; | ||
87 | Pixmap m_pixmap; | ||
79 | 88 | ||
80 | std::auto_ptr<AtomHandler> m_handler; | 89 | std::auto_ptr<AtomHandler> m_handler; |
81 | 90 | ||
diff --git a/src/ToolFactory.cc b/src/ToolFactory.cc index c56645a..eaff8f3 100644 --- a/src/ToolFactory.cc +++ b/src/ToolFactory.cc | |||
@@ -1,5 +1,5 @@ | |||
1 | // ToolFactory.cc for Fluxbox | 1 | // ToolFactory.cc for Fluxbox |
2 | // Copyright (c) 2003-2004 Henrik Kinnunen (fluxgen at users.sourceforge.net) | 2 | // Copyright (c) 2003-2005 Henrik Kinnunen (fluxgen at users.sourceforge.net) |
3 | // | 3 | // |
4 | // Permission is hereby granted, free of charge, to any person obtaining a | 4 | // Permission is hereby granted, free of charge, to any person obtaining a |
5 | // copy of this software and associated documentation files (the "Software"), | 5 | // copy of this software and associated documentation files (the "Software"), |
@@ -77,6 +77,8 @@ ToolFactory::ToolFactory(BScreen &screen):m_screen(screen), | |||
77 | m_clock_theme(screen.screenNumber(), "toolbar.clock", "Toolbar.Clock"), | 77 | m_clock_theme(screen.screenNumber(), "toolbar.clock", "Toolbar.Clock"), |
78 | m_button_theme(new ButtonTheme(screen.screenNumber(), "toolbar.button", "Toolbar.Button", | 78 | m_button_theme(new ButtonTheme(screen.screenNumber(), "toolbar.button", "Toolbar.Button", |
79 | "toolbar.clock", "Toolbar.Clock")), | 79 | "toolbar.clock", "Toolbar.Clock")), |
80 | m_systray_theme(new ButtonTheme(screen.screenNumber(), "toolbar.systray", "Toolbar.Systray", | ||
81 | "toolbar.clock", "Toolbar.Systray")), | ||
80 | m_workspace_theme(new WorkspaceNameTheme(screen.screenNumber(), "toolbar.workspace", "Toolbar.Workspace")), | 82 | m_workspace_theme(new WorkspaceNameTheme(screen.screenNumber(), "toolbar.workspace", "Toolbar.Workspace")), |
81 | m_iconbar_theme(screen.screenNumber(), "toolbar.iconbar", "Toolbar.Iconbar") { | 83 | m_iconbar_theme(screen.screenNumber(), "toolbar.iconbar", "Toolbar.Iconbar") { |
82 | 84 | ||
@@ -97,10 +99,9 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow & | |||
97 | witem->button().setOnClick(showmenu); | 99 | witem->button().setOnClick(showmenu); |
98 | item = witem; | 100 | item = witem; |
99 | } else if (name == "iconbar") { | 101 | } else if (name == "iconbar") { |
100 | item = new IconbarTool(parent, m_iconbar_theme, | 102 | item = new IconbarTool(parent, m_iconbar_theme, screen(), tbar.menu()); |
101 | screen(), tbar.menu()); | ||
102 | } else if (name == "systemtray") { | 103 | } else if (name == "systemtray") { |
103 | item = new SystemTray(parent); | 104 | item = new SystemTray(parent, dynamic_cast<ButtonTheme &>(*m_systray_theme), screen()); |
104 | } else if (name == "clock") { | 105 | } else if (name == "clock") { |
105 | item = new ClockTool(parent, m_clock_theme, screen(), tbar.menu()); | 106 | item = new ClockTool(parent, m_clock_theme, screen(), tbar.menu()); |
106 | } else if (name == "nextworkspace" || | 107 | } else if (name == "nextworkspace" || |
diff --git a/src/ToolFactory.hh b/src/ToolFactory.hh index 01a3d74..3def7f7 100644 --- a/src/ToolFactory.hh +++ b/src/ToolFactory.hh | |||
@@ -52,7 +52,9 @@ public: | |||
52 | private: | 52 | private: |
53 | BScreen &m_screen; | 53 | BScreen &m_screen; |
54 | ToolTheme m_clock_theme; | 54 | ToolTheme m_clock_theme; |
55 | std::auto_ptr<ToolTheme> m_button_theme, m_workspace_theme; | 55 | std::auto_ptr<ToolTheme> m_button_theme; |
56 | std::auto_ptr<ToolTheme> m_workspace_theme; | ||
57 | std::auto_ptr<ToolTheme> m_systray_theme; | ||
56 | IconbarTheme m_iconbar_theme; | 58 | IconbarTheme m_iconbar_theme; |
57 | }; | 59 | }; |
58 | 60 | ||