all repos — fluxbox @ 2c6647112667109b109e578ffd55ae8409c9e1af

custom fork of the fluxbox windowmanager

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.
Thomas Lübking thomas.luebking@gmail.com
commit

2c6647112667109b109e578ffd55ae8409c9e1af

parent

ecdaab5edf619d3cdc7bba9856d5f92068c28c83

4 files changed, 44 insertions(+), 3 deletions(-)

jump to
M src/FbTk/KeyUtil.ccsrc/FbTk/KeyUtil.cc

@@ -144,7 +144,7 @@ // Grab with numlock, capslock and scrlock

for (int i = 0; i < 8; i++) { XGrabButton(display, button, mod | (i & 1 ? LockMask : 0) | (i & 2 ? nummod : 0) | (i & 4 ? scrollmod : 0), - win, False, event_mask, GrabModeAsync, GrabModeAsync, + win, False, event_mask, GrabModeSync, GrabModeAsync, None, cursor); }
M src/SystemTray.ccsrc/SystemTray.cc

@@ -77,6 +77,8 @@ }

}; +static SystemTray *s_theoneandonly = 0; + /// helper class for tray windows, so we dont call XDestroyWindow class SystemTray::TrayWindow : public FbTk::FbWindow { public:

@@ -220,6 +222,8 @@

// set owner XSetSelectionOwner(disp, tray_atom, m_selection_owner.window(), CurrentTime); + s_theoneandonly = this; + m_handler.reset(new SystemTrayHandler(*this)); m_handler.get()->setName(atom_name);

@@ -247,6 +251,8 @@ }

SystemTray::~SystemTray() { // remove us, else fluxbox might delete the memory too + if (s_theoneandonly == this) + s_theoneandonly = 0; Fluxbox* fluxbox = Fluxbox::instance(); fluxbox->removeAtomHandler(m_handler.get()); Display *disp = fluxbox->display();

@@ -589,3 +595,10 @@ atom_name += FbTk::StringUtil::number2String(screen_nr);

return atom_name; } + +bool SystemTray::doesControl(Window win) { + if (win == None || !s_theoneandonly) + return false; + return win == s_theoneandonly->window().window() || + s_theoneandonly->findClient(win) != s_theoneandonly->m_clients.end(); +}
M src/SystemTray.hhsrc/SystemTray.hh

@@ -87,6 +87,8 @@ static std::string getNetSystemTrayAtom(int screen_nr);

static Atom getXEmbedInfoAtom(); + static bool doesControl(Window win); + private: void update();
M src/Toolbar.ccsrc/Toolbar.cc

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

#include "Keys.hh" #include "Screen.hh" #include "ScreenPlacement.hh" +#include "SystemTray.hh" #include "WindowCmd.hh" #include "Strut.hh"

@@ -512,14 +513,39 @@

void Toolbar::buttonPressEvent(XButtonEvent &be) { + Display *dpy = Fluxbox::instance()->display(); + if (be.subwindow) { + // Do not intercept mouse events that are meant for the tray icon + if (SystemTray::doesControl(be.subwindow)) { + XAllowEvents(dpy, ReplayPointer, CurrentTime); + return; + } +#if 0 + // Unfortunately, the subwindow isn't exactly a reliable source here, so + // we COULD query the pointer (what will usually return the systray itself) and + // check that as well. NOTICE that due to the async nature of X11, the + // pointer might have moved and the result isn't correct either. + Window wr, wc; int junk; unsigned int ujunk; + XQueryPointer(dpy, be.window, &wr, &wc, &junk, &junk, &junk, &junk, &ujunk); + if (SystemTray::doesControl(wc)) { + XAllowEvents(dpy, ReplayPointer, CurrentTime); + return; + } +#endif + } + if (Fluxbox::instance()->keys()->doAction(be.type, be.state, be.button, - Keys::ON_TOOLBAR, 0, be.time)) + Keys::ON_TOOLBAR, 0, be.time)) { + XAllowEvents(dpy, SyncPointer, CurrentTime); return; + } if (be.button == 1) raise(); - if (be.button != 2) + if (be.button != 2 || be.subwindow) { // only handle direct toolbar MMBs + XAllowEvents(dpy, ReplayPointer, CurrentTime); return; + } screen() .placementStrategy()