aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Tiefenbruck <mark@fluxbox.org>2007-12-22 05:24:13 (GMT)
committerMark Tiefenbruck <mark@fluxbox.org>2007-12-22 05:24:13 (GMT)
commit0a67bdce416cb18a9c2f356262b62e1fad8dd52f (patch)
tree17eb66f2bf3c4b5e920e1045aa75a83b7f058e02
parent0906477984edbd9f6e62fed3800ea9a441919a58 (diff)
downloadfluxbox-0a67bdce416cb18a9c2f356262b62e1fad8dd52f.zip
fluxbox-0a67bdce416cb18a9c2f356262b62e1fad8dd52f.tar.bz2
make better decisions about when to allow stealing the focus
-rw-r--r--src/Ewmh.cc2
-rw-r--r--src/Window.cc54
-rw-r--r--src/Window.hh2
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
2234bool FluxboxWindow::allowsFocusFromClient() { 2235bool 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(); }