From bb6906fa80c06fc23975d7520b3e8919423a29b4 Mon Sep 17 00:00:00 2001 From: markt Date: Thu, 22 Nov 2007 20:21:47 +0000 Subject: added special FocusIn/Out MouseOver/Out ChangeWorkspace keys --- ChangeLog | 14 ++++++++++++++ src/FbCommandFactory.cc | 7 +++---- src/FbTk/LogicCommands.hh | 8 ++++---- src/FbWinFrame.cc | 6 ++++-- src/Keys.cc | 33 +++++++++++++++++++++++++++++---- src/Screen.cc | 2 ++ src/Toolbar.cc | 11 ++++++++--- src/Window.cc | 26 ++++++++++++++++++++++++++ 8 files changed, 90 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0e38acf..5971f05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,20 @@ (Format: Year/Month/Day) Changes for 1.0.1: *07/11/22: + * Added some new special keys to the keys file: FocusIn, FocusOut, MouseOver, + MouseOut, ChangeWorkspace (Mark) + - FocusIn/FocusOut correspond to a window gaining or losing focus, e.g. the + following will raise all xterms when one gains focus: + FocusIn :If {Matches (xterm)} {Raise (xterm)} {} + - MouseOver/MouseOut correspond to the mouse moving over the window or + toolbar (when used with OnToolbar) -- OnDesktop not yet supported, e.g. + the following will unshade a window when you move your mouse over it with + alt pressed: + Mod1 MouseOver :If {Matches (shaded=yes)} {Shade} {} + - ChangeWorkspace corresponds to the workspace being changed, e.g. the + following will set a different wallpaper for each workspace: + ChangeWorkspace :Exec fbsetbg ~/.fluxbox/bg$(xprop -root _NET_CURRENT_DESKTOP | awk '{print $3}').png + Keys.cc Window.cc Screen.cc Toolbar.cc * Added translations for zh_TW (thanks Wei-Lun Chao) * Fix division by 0 error when resize increments are set to 0 by an application, bug #1836182 diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc index 92099f2..8f5dcf8 100644 --- a/src/FbCommandFactory.cc +++ b/src/FbCommandFactory.cc @@ -809,17 +809,16 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, pos = err; err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() + pos, '{', '}', " \t\n", true); - if (err > 0) - t = CommandParser::instance().parseLine(cmd, trusted); - if (err == 0 || *t == 0) + if (err == 0) return 0; + t = CommandParser::instance().parseLine(cmd, trusted); pos += err; err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() + pos, '{', '}', " \t\n", true); if (err > 0) f = CommandParser::instance().parseLine(cmd, trusted); - if (err == 0 || *f == 0) + if (err == 0 || *t == 0 && *f == 0) return 0; return new FbTk::IfCommand(cond, t, f); diff --git a/src/FbTk/LogicCommands.hh b/src/FbTk/LogicCommands.hh index a94dad8..4f20864 100644 --- a/src/FbTk/LogicCommands.hh +++ b/src/FbTk/LogicCommands.hh @@ -38,10 +38,10 @@ public: RefCount &t, RefCount &f): m_cond(cond), m_t(t), m_f(f) { } void execute() { - if (m_cond->bool_execute()) - m_t->execute(); - else - m_f->execute(); + if (m_cond->bool_execute()) { + if (*m_t) m_t->execute(); + } else + if (*m_f) m_f->execute(); } private: diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc index 83610ea..f710416 100644 --- a/src/FbWinFrame.cc +++ b/src/FbWinFrame.cc @@ -55,7 +55,8 @@ FbWinFrame::FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageContr m_imagectrl(imgctrl), m_window(theme.screenNum(), x, y, width, height, ButtonPressMask | ButtonReleaseMask | - ButtonMotionMask | EnterWindowMask, true), + ButtonMotionMask | EnterWindowMask | + LeaveWindowMask, true), m_layeritem(window(), layer), m_titlebar(m_window, 0, 0, 100, 16, ButtonPressMask | ButtonReleaseMask | @@ -666,7 +667,8 @@ void FbWinFrame::setClientWindow(FbTk::FbWindow &win) { FocusChangeMask | KeyPressMask); m_window.setEventMask(ButtonPressMask | ButtonReleaseMask | - ButtonMotionMask | EnterWindowMask | SubstructureRedirectMask); + ButtonMotionMask | EnterWindowMask | + LeaveWindowMask | SubstructureRedirectMask); XFlush(win.display()); diff --git a/src/Keys.cc b/src/Keys.cc index 2d26ab8..f3cd092 100644 --- a/src/Keys.cc +++ b/src/Keys.cc @@ -307,10 +307,35 @@ bool Keys::addBinding(const string &linebuffer) { context |= ON_WINDOW; else if (strcasecmp("NONE",val[argc].c_str())) { // check if it's a mouse button - if (!strcasecmp(val[argc].substr(0,5).c_str(), "mouse") && - val[argc].length() > 5) { + if (strcasecmp("focusin", val[argc].c_str()) == 0) { + context = ON_WINDOW; + mod = key = 0; + type = FocusIn; + } else if (strcasecmp("focusout", val[argc].c_str()) == 0) { + context = ON_WINDOW; + mod = key = 0; + type = FocusOut; + } else if (strcasecmp("changeworkspace", + val[argc].c_str()) == 0) { + context = ON_DESKTOP; + mod = key = 0; + type = FocusIn; + } else if (strcasecmp("mouseover", val[argc].c_str()) == 0) { + type = EnterNotify; + if (!(context & (ON_WINDOW|ON_TOOLBAR))) + context |= ON_WINDOW; + key = 0; + } else if (strcasecmp("mouseout", val[argc].c_str()) == 0) { + type = LeaveNotify; + if (!(context & (ON_WINDOW|ON_TOOLBAR))) + context |= ON_WINDOW; + key = 0; + } else if (strcasecmp(val[argc].substr(0,5).c_str(), + "mouse") == 0 && + val[argc].length() > 5) { type = ButtonPress; - key = atoi(val[argc].substr(5,val[argc].length()-5).c_str()); + key = atoi(val[argc].substr(5, + val[argc].length()-5).c_str()); // keycode covers the following three two-byte cases: // 0x - hex // +[1-9] - number between +1 and +9 @@ -331,7 +356,7 @@ bool Keys::addBinding(const string &linebuffer) { type = KeyPress; } - if (key == 0) + if (key == 0 && (type == KeyPress || type == ButtonPress)) return false; if (!first_new_key) { first_new_keylist = current_key; diff --git a/src/Screen.cc b/src/Screen.cc index 0c26a70..155a113 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -1237,6 +1237,8 @@ void BScreen::changeWorkspaceID(unsigned int id, bool revert) { m_currentworkspace_sig.notify(); + // do this after atom handlers, so scripts can access new workspace number + Fluxbox::instance()->keys()->doAction(FocusIn, 0, 0, Keys::ON_DESKTOP); } diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 32925de..2694a4c 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -556,7 +556,9 @@ void Toolbar::buttonPressEvent(XButtonEvent &be) { } -void Toolbar::enterNotifyEvent(XCrossingEvent ¬_used) { +void Toolbar::enterNotifyEvent(XCrossingEvent &ce) { + Fluxbox::instance()->keys()->doAction(ce.type, ce.state, 0, + Keys::ON_TOOLBAR); if (! doAutoHide()) { if (isHidden()) toggleHidden(); @@ -573,13 +575,16 @@ void Toolbar::enterNotifyEvent(XCrossingEvent ¬_used) { } void Toolbar::leaveNotifyEvent(XCrossingEvent &event) { - if (! doAutoHide()) - return; // still inside? if (event.x_root > x() && event.x_root <= (int)(x() + width()) && event.y_root > y() && event.y_root <= (int)(y() + height())) return; + Fluxbox::instance()->keys()->doAction(event.type, event.state, 0, + Keys::ON_TOOLBAR); + if (! doAutoHide()) + return; + if (isHidden()) { if (m_hide_timer.isTiming()) m_hide_timer.stop(); diff --git a/src/Window.cc b/src/Window.cc index 0fb8673..0db3b80 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -1930,6 +1930,9 @@ void FluxboxWindow::setFocusFlag(bool focus) { m_focussig.notify(); if (m_client) m_client->focusSig().notify(); + WindowCmd::setClient(m_client); + Fluxbox::instance()->keys()->doAction(focus ? FocusIn : FocusOut, 0, 0, + Keys::ON_WINDOW); } } @@ -2942,6 +2945,12 @@ void FluxboxWindow::enterNotifyEvent(XCrossingEvent &ev) { return; } + if (ev.window == frame().window()) { + WindowCmd::setWindow(this); + Fluxbox::instance()->keys()->doAction(ev.type, ev.state, 0, + Keys::ON_WINDOW); + } + WinClient *client = 0; if (screen().focusControl().isMouseTabFocus()) { // determine if we're in a label button (tab) @@ -2984,6 +2993,23 @@ void FluxboxWindow::enterNotifyEvent(XCrossingEvent &ev) { } void FluxboxWindow::leaveNotifyEvent(XCrossingEvent &ev) { + + // ignore grab activates, or if we're not visible + if (ev.mode == NotifyGrab || ev.mode == NotifyUngrab || + !isVisible()) { + return; + } + + // still inside? + if (ev.x_root > frame().x() && ev.y_root > frame().y() && + ev.x_root <= (int)(frame().x() + frame().width()) && + ev.y_root <= (int)(frame().y() + frame().height())) + return; + + WindowCmd::setWindow(this); + Fluxbox::instance()->keys()->doAction(ev.type, ev.state, 0, + Keys::ON_WINDOW); + // I hope commenting this out is right - simon 21jul2003 //if (ev.window == frame().window()) //installColormap(false); -- cgit v0.11.2