added special FocusIn/Out MouseOver/Out ChangeWorkspace keys

This commit is contained in:
markt 2007-11-22 20:21:47 +00:00
parent 58cd017db0
commit bb6906fa80
8 changed files with 90 additions and 17 deletions

View file

@ -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

View file

@ -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);

View file

@ -38,10 +38,10 @@ public:
RefCount<Command> &t, RefCount<Command> &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:

View file

@ -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());

View file

@ -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;

View file

@ -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);
}

View file

@ -556,7 +556,9 @@ void Toolbar::buttonPressEvent(XButtonEvent &be) {
}
void Toolbar::enterNotifyEvent(XCrossingEvent &not_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 &not_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();

View file

@ -1930,6 +1930,9 @@ void FluxboxWindow::setFocusFlag(bool focus) {
m_focussig.notify();
if (m_client)
m_client->focusSig().notify();
WindowCmd<void>::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<void>::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<void>::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);