diff options
author | Mark Tiefenbruck <mark@fluxbox.org> | 2007-12-22 05:24:13 (GMT) |
---|---|---|
committer | Mark Tiefenbruck <mark@fluxbox.org> | 2007-12-22 05:24:13 (GMT) |
commit | 0a67bdce416cb18a9c2f356262b62e1fad8dd52f (patch) | |
tree | 17eb66f2bf3c4b5e920e1045aa75a83b7f058e02 | |
parent | 0906477984edbd9f6e62fed3800ea9a441919a58 (diff) | |
download | fluxbox-0a67bdce416cb18a9c2f356262b62e1fad8dd52f.zip fluxbox-0a67bdce416cb18a9c2f356262b62e1fad8dd52f.tar.bz2 |
make better decisions about when to allow stealing the focus
-rw-r--r-- | src/Ewmh.cc | 2 | ||||
-rw-r--r-- | src/Window.cc | 54 | ||||
-rw-r--r-- | src/Window.hh | 2 |
3 files changed, 35 insertions, 23 deletions
diff --git a/src/Ewmh.cc b/src/Ewmh.cc index ee98944..6f0d829 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc | |||
@@ -749,7 +749,7 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, | |||
749 | 749 | ||
750 | // ce.data.l[0] == 2 means the request came from a pager | 750 | // ce.data.l[0] == 2 means the request came from a pager |
751 | if (winclient->fbwindow() && (ce.data.l[0] == 2 || | 751 | if (winclient->fbwindow() && (ce.data.l[0] == 2 || |
752 | winclient->fbwindow()->allowsFocusFromClient())) { | 752 | winclient->fbwindow()->focusRequestFromClient(*winclient))) { |
753 | winclient->focus(); | 753 | winclient->focus(); |
754 | winclient->fbwindow()->raise(); | 754 | winclient->fbwindow()->raise(); |
755 | } | 755 | } |
diff --git a/src/Window.cc b/src/Window.cc index 4c1bf64..8d2bcc4 100644 --- a/src/Window.cc +++ b/src/Window.cc | |||
@@ -545,10 +545,12 @@ void FluxboxWindow::init() { | |||
545 | iconify(); | 545 | iconify(); |
546 | } else if (m_workspace_number == screen().currentWorkspaceID()) { | 546 | } else if (m_workspace_number == screen().currentWorkspaceID()) { |
547 | iconic = true; | 547 | iconic = true; |
548 | deiconify(); | 548 | deiconify(false); |
549 | // check if we should prevent this window from gaining focus | 549 | // check if we should prevent this window from gaining focus |
550 | if (!allowsFocusFromClient() || Fluxbox::instance()->isStartup()) | 550 | m_focused = false; // deiconify sets this |
551 | m_focused = false; | 551 | if (!Fluxbox::instance()->isStartup() && |
552 | screen().focusControl().focusNew()) | ||
553 | m_focused = focusRequestFromClient(*m_client); | ||
552 | } | 554 | } |
553 | 555 | ||
554 | if (fullscreen) { | 556 | if (fullscreen) { |
@@ -655,7 +657,7 @@ void FluxboxWindow::attachClient(WinClient &client, int x, int y) { | |||
655 | 657 | ||
656 | // we use m_focused as a signal to focus the window when mapped | 658 | // we use m_focused as a signal to focus the window when mapped |
657 | if (focus_new && !is_startup) | 659 | if (focus_new && !is_startup) |
658 | m_focused = true; | 660 | m_focused = focusRequestFromClient(client); |
659 | focused_win = (focus_new || is_startup) ? &client : m_client; | 661 | focused_win = (focus_new || is_startup) ? &client : m_client; |
660 | 662 | ||
661 | client.saveBlackboxAttribs(m_blackbox_attrib, | 663 | client.saveBlackboxAttribs(m_blackbox_attrib, |
@@ -1008,7 +1010,8 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { | |||
1008 | WinClient *old = m_client; | 1010 | WinClient *old = m_client; |
1009 | m_client = &client; | 1011 | m_client = &client; |
1010 | m_client->raise(); | 1012 | m_client->raise(); |
1011 | m_client->focusSig().notify(); | 1013 | if (setinput != m_focused || setinput && m_client != old) |
1014 | m_client->focusSig().notify(); | ||
1012 | titleSig().notify(); | 1015 | titleSig().notify(); |
1013 | 1016 | ||
1014 | #ifdef DEBUG | 1017 | #ifdef DEBUG |
@@ -1019,7 +1022,6 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { | |||
1019 | frame().setLabelButtonFocus(*button); | 1022 | frame().setLabelButtonFocus(*button); |
1020 | frame().setShapingClient(&client, false); | 1023 | frame().setShapingClient(&client, false); |
1021 | 1024 | ||
1022 | setinput = setinput || m_focused && !screen().focusControl().isCycling(); | ||
1023 | bool ret = setinput && focus(); | 1025 | bool ret = setinput && focus(); |
1024 | if (setinput) { | 1026 | if (setinput) { |
1025 | // restore old client until focus event comes | 1027 | // restore old client until focus event comes |
@@ -2222,31 +2224,34 @@ void FluxboxWindow::mapRequestEvent(XMapRequestEvent &re) { | |||
2222 | // Note: this function never gets called from WithdrawnState | 2224 | // Note: this function never gets called from WithdrawnState |
2223 | // initial state is handled in restoreAttributes() and init() | 2225 | // initial state is handled in restoreAttributes() and init() |
2224 | 2226 | ||
2225 | // if the user doesn't want the window, then ignore request | 2227 | if (screen().focusControl().focusNew()) |
2226 | if (!allowsFocusFromClient()) | 2228 | m_focused = focusRequestFromClient(*client); |
2227 | return; | ||
2228 | 2229 | ||
2229 | setCurrentClient(*client, false); // focus handled on MapNotify | 2230 | setCurrentClient(*client, false); // focus handled on MapNotify |
2230 | deiconify(); | 2231 | deiconify(); |
2231 | 2232 | ||
2232 | } | 2233 | } |
2233 | 2234 | ||
2234 | bool FluxboxWindow::allowsFocusFromClient() { | 2235 | bool FluxboxWindow::focusRequestFromClient(WinClient &from) { |
2236 | |||
2237 | if (from.fbwindow() != this) | ||
2238 | return false; | ||
2235 | 2239 | ||
2240 | bool ret = true; | ||
2236 | // check what to do if window is on another workspace | 2241 | // check what to do if window is on another workspace |
2237 | if (screen().currentWorkspaceID() != workspaceNumber() && !isStuck()) { | 2242 | if (screen().currentWorkspaceID() != workspaceNumber() && !isStuck() && |
2238 | BScreen::FollowModel model = screen().getFollowModel(); | 2243 | screen().getFollowModel() == BScreen::IGNORE_OTHER_WORKSPACES) |
2239 | if (model == BScreen::IGNORE_OTHER_WORKSPACES) | 2244 | ret = false; |
2240 | return false; | ||
2241 | } | ||
2242 | 2245 | ||
2243 | FluxboxWindow *cur = FocusControl::focusedFbWindow(); | 2246 | FluxboxWindow *cur = FocusControl::focusedFbWindow(); |
2244 | WinClient *client = FocusControl::focusedWindow(); | 2247 | WinClient *client = FocusControl::focusedWindow(); |
2245 | if (cur && client && (m_client->isTransient() || cur->isTyping()) && | 2248 | if (ret && cur && getRootTransientFor(&from) != getRootTransientFor(client)) |
2246 | getRootTransientFor(m_client) != getRootTransientFor(client)) | 2249 | ret = !(cur->isFullscreen() && getOnHead() == cur->getOnHead()) && |
2247 | return false; | 2250 | !cur->isTyping(); |
2248 | 2251 | ||
2249 | return true; | 2252 | if (!ret) |
2253 | Fluxbox::instance()->attentionHandler().addAttention(from); | ||
2254 | return ret; | ||
2250 | 2255 | ||
2251 | } | 2256 | } |
2252 | 2257 | ||
@@ -2509,8 +2514,15 @@ void FluxboxWindow::configureRequestEvent(XConfigureRequestEvent &cr) { | |||
2509 | case Above: | 2514 | case Above: |
2510 | case TopIf: | 2515 | case TopIf: |
2511 | default: | 2516 | default: |
2512 | setCurrentClient(*client, m_focused); | 2517 | if (isFocused() && focusRequestFromClient(*client) || |
2513 | raise(); | 2518 | !FocusControl::focusedWindow()) { |
2519 | setCurrentClient(*client, true); | ||
2520 | raise(); | ||
2521 | } else if (getRootTransientFor(client) == | ||
2522 | getRootTransientFor(FocusControl::focusedWindow())) { | ||
2523 | setCurrentClient(*client, false); | ||
2524 | raise(); | ||
2525 | } | ||
2514 | break; | 2526 | break; |
2515 | 2527 | ||
2516 | case Below: | 2528 | case Below: |
diff --git a/src/Window.hh b/src/Window.hh index e75b84c..eeb7ae1 100644 --- a/src/Window.hh +++ b/src/Window.hh | |||
@@ -244,7 +244,7 @@ public: | |||
244 | * @return true if it took focus. | 244 | * @return true if it took focus. |
245 | */ | 245 | */ |
246 | bool focus(); | 246 | bool focus(); |
247 | bool allowsFocusFromClient(); | 247 | bool focusRequestFromClient(WinClient &from); |
248 | 248 | ||
249 | /// Raises the window and takes focus (if possible). | 249 | /// Raises the window and takes focus (if possible). |
250 | void raiseAndFocus() { raise(); focus(); } | 250 | void raiseAndFocus() { raise(); focus(); } |