aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lübking <thomas.luebking@gmail.com>2016-07-04 19:55:23 (GMT)
committerThomas Lübking <thomas.luebking@gmail.com>2016-08-27 07:36:19 (GMT)
commit2c6647112667109b109e578ffd55ae8409c9e1af (patch)
treedea7cbb288f2eb286ff5cb7a3a5bd70e833572c6
parentecdaab5edf619d3cdc7bba9856d5f92068c28c83 (diff)
downloadfluxbox-2c6647112667109b109e578ffd55ae8409c9e1af.zip
fluxbox-2c6647112667109b109e578ffd55ae8409c9e1af.tar.bz2
Replay toolbar button events
NOTICE!!!! THIS IS HIGHLY EXPERIMENTAL! The patch alters the button grab mode to GrabSync in order to ReplayPointer the event. THIS CAN FREEZE ANY INPUT TO FLUXBOX!!! The toolbar (and other things?) grab buttons in order to handle MouseN events for the entire bar, INCLUDING all child windows. This causes two problems: 1. The bar handles events which are not meant for fluxbox at all (but the systray icons) BUG: 940 2. The bar will intercept (and suck) *every* press, even if only doubleclicks are desired BUG: 949 The problem with this patch is that an oversight here has the potential to completely freeze input event processing in fluxbox (ie. the process needs to be killed from outside), SO IT NEEDS TESTING! As much as possible.
-rw-r--r--src/FbTk/KeyUtil.cc2
-rw-r--r--src/SystemTray.cc13
-rw-r--r--src/SystemTray.hh2
-rw-r--r--src/Toolbar.cc30
4 files changed, 44 insertions, 3 deletions
diff --git a/src/FbTk/KeyUtil.cc b/src/FbTk/KeyUtil.cc
index 6661bb7..10bc118 100644
--- a/src/FbTk/KeyUtil.cc
+++ b/src/FbTk/KeyUtil.cc
@@ -144,7 +144,7 @@ void KeyUtil::grabButton(unsigned int button, unsigned int mod, Window win,
144 for (int i = 0; i < 8; i++) { 144 for (int i = 0; i < 8; i++) {
145 XGrabButton(display, button, mod | (i & 1 ? LockMask : 0) | 145 XGrabButton(display, button, mod | (i & 1 ? LockMask : 0) |
146 (i & 2 ? nummod : 0) | (i & 4 ? scrollmod : 0), 146 (i & 2 ? nummod : 0) | (i & 4 ? scrollmod : 0),
147 win, False, event_mask, GrabModeAsync, GrabModeAsync, 147 win, False, event_mask, GrabModeSync, GrabModeAsync,
148 None, cursor); 148 None, cursor);
149 } 149 }
150 150
diff --git a/src/SystemTray.cc b/src/SystemTray.cc
index e45669e..4fa9da3 100644
--- a/src/SystemTray.cc
+++ b/src/SystemTray.cc
@@ -77,6 +77,8 @@ void getScreenCoordinates(Window win, int x, int y, int &screen_x, int &screen_y
77 77
78}; 78};
79 79
80static SystemTray *s_theoneandonly = 0;
81
80/// helper class for tray windows, so we dont call XDestroyWindow 82/// helper class for tray windows, so we dont call XDestroyWindow
81class SystemTray::TrayWindow : public FbTk::FbWindow { 83class SystemTray::TrayWindow : public FbTk::FbWindow {
82public: 84public:
@@ -220,6 +222,8 @@ SystemTray::SystemTray(const FbTk::FbWindow& parent,
220 // set owner 222 // set owner
221 XSetSelectionOwner(disp, tray_atom, m_selection_owner.window(), CurrentTime); 223 XSetSelectionOwner(disp, tray_atom, m_selection_owner.window(), CurrentTime);
222 224
225 s_theoneandonly = this;
226
223 m_handler.reset(new SystemTrayHandler(*this)); 227 m_handler.reset(new SystemTrayHandler(*this));
224 228
225 m_handler.get()->setName(atom_name); 229 m_handler.get()->setName(atom_name);
@@ -247,6 +251,8 @@ SystemTray::SystemTray(const FbTk::FbWindow& parent,
247 251
248SystemTray::~SystemTray() { 252SystemTray::~SystemTray() {
249 // remove us, else fluxbox might delete the memory too 253 // remove us, else fluxbox might delete the memory too
254 if (s_theoneandonly == this)
255 s_theoneandonly = 0;
250 Fluxbox* fluxbox = Fluxbox::instance(); 256 Fluxbox* fluxbox = Fluxbox::instance();
251 fluxbox->removeAtomHandler(m_handler.get()); 257 fluxbox->removeAtomHandler(m_handler.get());
252 Display *disp = fluxbox->display(); 258 Display *disp = fluxbox->display();
@@ -589,3 +595,10 @@ string SystemTray::getNetSystemTrayAtom(int screen_nr) {
589 595
590 return atom_name; 596 return atom_name;
591} 597}
598
599bool SystemTray::doesControl(Window win) {
600 if (win == None || !s_theoneandonly)
601 return false;
602 return win == s_theoneandonly->window().window() ||
603 s_theoneandonly->findClient(win) != s_theoneandonly->m_clients.end();
604}
diff --git a/src/SystemTray.hh b/src/SystemTray.hh
index 61cd1bb..470f9b9 100644
--- a/src/SystemTray.hh
+++ b/src/SystemTray.hh
@@ -87,6 +87,8 @@ public:
87 87
88 static Atom getXEmbedInfoAtom(); 88 static Atom getXEmbedInfoAtom();
89 89
90 static bool doesControl(Window win);
91
90private: 92private:
91 void update(); 93 void update();
92 94
diff --git a/src/Toolbar.cc b/src/Toolbar.cc
index 92ab81a..bfaec94 100644
--- a/src/Toolbar.cc
+++ b/src/Toolbar.cc
@@ -31,6 +31,7 @@
31#include "Keys.hh" 31#include "Keys.hh"
32#include "Screen.hh" 32#include "Screen.hh"
33#include "ScreenPlacement.hh" 33#include "ScreenPlacement.hh"
34#include "SystemTray.hh"
34#include "WindowCmd.hh" 35#include "WindowCmd.hh"
35 36
36#include "Strut.hh" 37#include "Strut.hh"
@@ -512,14 +513,39 @@ void Toolbar::reconfigure() {
512 513
513 514
514void Toolbar::buttonPressEvent(XButtonEvent &be) { 515void Toolbar::buttonPressEvent(XButtonEvent &be) {
516 Display *dpy = Fluxbox::instance()->display();
517 if (be.subwindow) {
518 // Do not intercept mouse events that are meant for the tray icon
519 if (SystemTray::doesControl(be.subwindow)) {
520 XAllowEvents(dpy, ReplayPointer, CurrentTime);
521 return;
522 }
523#if 0
524 // Unfortunately, the subwindow isn't exactly a reliable source here, so
525 // we COULD query the pointer (what will usually return the systray itself) and
526 // check that as well. NOTICE that due to the async nature of X11, the
527 // pointer might have moved and the result isn't correct either.
528 Window wr, wc; int junk; unsigned int ujunk;
529 XQueryPointer(dpy, be.window, &wr, &wc, &junk, &junk, &junk, &junk, &ujunk);
530 if (SystemTray::doesControl(wc)) {
531 XAllowEvents(dpy, ReplayPointer, CurrentTime);
532 return;
533 }
534#endif
535 }
536
515 if (Fluxbox::instance()->keys()->doAction(be.type, be.state, be.button, 537 if (Fluxbox::instance()->keys()->doAction(be.type, be.state, be.button,
516 Keys::ON_TOOLBAR, 0, be.time)) 538 Keys::ON_TOOLBAR, 0, be.time)) {
539 XAllowEvents(dpy, SyncPointer, CurrentTime);
517 return; 540 return;
541 }
518 542
519 if (be.button == 1) 543 if (be.button == 1)
520 raise(); 544 raise();
521 if (be.button != 2) 545 if (be.button != 2 || be.subwindow) { // only handle direct toolbar MMBs
546 XAllowEvents(dpy, ReplayPointer, CurrentTime);
522 return; 547 return;
548 }
523 549
524 screen() 550 screen()
525 .placementStrategy() 551 .placementStrategy()