diff options
-rw-r--r-- | src/FocusControl.cc | 7 | ||||
-rw-r--r-- | src/Remember.cc | 65 | ||||
-rw-r--r-- | src/Remember.hh | 2 | ||||
-rw-r--r-- | src/Window.cc | 13 | ||||
-rw-r--r-- | src/Window.hh | 17 |
5 files changed, 102 insertions, 2 deletions
diff --git a/src/FocusControl.cc b/src/FocusControl.cc index 3be7937..f59b5ff 100644 --- a/src/FocusControl.cc +++ b/src/FocusControl.cc | |||
@@ -588,6 +588,13 @@ void FocusControl::setFocusedWindow(WinClient *client) { | |||
588 | } | 588 | } |
589 | } | 589 | } |
590 | 590 | ||
591 | if (client != expectingFocus() && s_focused_window && | ||
592 | ((s_focused_fbwindow->focusProtection() & Focus::Lock) || | ||
593 | (client && client->fbwindow() && (client->fbwindow()->focusProtection() & Focus::Deny)))) { | ||
594 | s_focused_window->focus(); | ||
595 | return; | ||
596 | } | ||
597 | |||
591 | BScreen *old_screen = | 598 | BScreen *old_screen = |
592 | FocusControl::focusedWindow() ? | 599 | FocusControl::focusedWindow() ? |
593 | &FocusControl::focusedWindow()->screen() : 0; | 600 | &FocusControl::focusedWindow()->screen() : 0; |
diff --git a/src/Remember.cc b/src/Remember.cc index 6dcd378..43a4d16 100644 --- a/src/Remember.cc +++ b/src/Remember.cc | |||
@@ -98,6 +98,7 @@ public: | |||
98 | void forgetIconHiddenstate() { iconhiddenstate_remember= false; } | 98 | void forgetIconHiddenstate() { iconhiddenstate_remember= false; } |
99 | void forgetStuckstate() { stuckstate_remember = false; } | 99 | void forgetStuckstate() { stuckstate_remember = false; } |
100 | void forgetFocusNewWindow() { focusnewwindow_remember = false; } | 100 | void forgetFocusNewWindow() { focusnewwindow_remember = false; } |
101 | void forgetFocusProtection() { focusprotection_remember = false; } | ||
101 | void forgetJumpworkspace() { jumpworkspace_remember = false; } | 102 | void forgetJumpworkspace() { jumpworkspace_remember = false; } |
102 | void forgetLayer() { layer_remember = false; } | 103 | void forgetLayer() { layer_remember = false; } |
103 | void forgetSaveOnClose() { save_on_close_remember = false; } | 104 | void forgetSaveOnClose() { save_on_close_remember = false; } |
@@ -140,6 +141,8 @@ public: | |||
140 | { stuckstate = state; stuckstate_remember = true; } | 141 | { stuckstate = state; stuckstate_remember = true; } |
141 | void rememberFocusNewWindow(bool state) | 142 | void rememberFocusNewWindow(bool state) |
142 | { focusnewwindow = state; focusnewwindow_remember = true; } | 143 | { focusnewwindow = state; focusnewwindow_remember = true; } |
144 | void rememberFocusProtection(unsigned int protect) | ||
145 | { focusprotection = protect; focusprotection_remember = true; } | ||
143 | void rememberJumpworkspace(bool state) | 146 | void rememberJumpworkspace(bool state) |
144 | { jumpworkspace = state; jumpworkspace_remember = true; } | 147 | { jumpworkspace = state; jumpworkspace_remember = true; } |
145 | void rememberLayer(int layernum) | 148 | void rememberLayer(int layernum) |
@@ -191,6 +194,9 @@ public: | |||
191 | bool focusnewwindow_remember; | 194 | bool focusnewwindow_remember; |
192 | bool focusnewwindow; | 195 | bool focusnewwindow; |
193 | 196 | ||
197 | bool focusprotection_remember; | ||
198 | unsigned int focusprotection; | ||
199 | |||
194 | bool focushiddenstate_remember; | 200 | bool focushiddenstate_remember; |
195 | bool focushiddenstate; | 201 | bool focushiddenstate; |
196 | 202 | ||
@@ -242,6 +248,7 @@ void Application::reset() { | |||
242 | shadedstate_remember = | 248 | shadedstate_remember = |
243 | stuckstate_remember = | 249 | stuckstate_remember = |
244 | focusnewwindow_remember = | 250 | focusnewwindow_remember = |
251 | focusprotection_remember = | ||
245 | tabstate_remember = | 252 | tabstate_remember = |
246 | workspace_remember = | 253 | workspace_remember = |
247 | head_remember = | 254 | head_remember = |
@@ -549,6 +556,26 @@ int parseApp(ifstream &file, Application &app, string *first_line = 0) { | |||
549 | app.rememberStuckstate(str_label == "yes"); | 556 | app.rememberStuckstate(str_label == "yes"); |
550 | } else if (str_key == "focusnewwindow") { | 557 | } else if (str_key == "focusnewwindow") { |
551 | app.rememberFocusNewWindow(str_label == "yes"); | 558 | app.rememberFocusNewWindow(str_label == "yes"); |
559 | } else if (str_key == "focusprotection") { | ||
560 | Focus::Protection protect = Focus::NoProtection; | ||
561 | std::list<std::string> labels; | ||
562 | FbTk::StringUtil::stringtok(labels, str_label, ", "); | ||
563 | std::list<std::string>::iterator it = labels.begin(); | ||
564 | for (; it != labels.end(); ++it) { | ||
565 | if (*it == "lock") | ||
566 | protect = (protect & ~Focus::Deny) | Focus::Lock; | ||
567 | else if (*it == "deny") | ||
568 | protect = (protect & ~Focus::Lock) | Focus::Deny; | ||
569 | else if (*it == "gain") | ||
570 | protect = (protect & ~Focus::Refuse) | Focus::Gain; | ||
571 | else if (*it == "refuse") | ||
572 | protect = (protect & ~Focus::Gain) | Focus::Refuse; | ||
573 | else if (*it == "none") | ||
574 | protect = Focus::NoProtection; | ||
575 | else | ||
576 | had_error = 1; | ||
577 | } | ||
578 | app.rememberFocusProtection(protect); | ||
552 | } else if (str_key == "minimized") { | 579 | } else if (str_key == "minimized") { |
553 | app.rememberMinimizedstate(str_label == "yes"); | 580 | app.rememberMinimizedstate(str_label == "yes"); |
554 | } else if (str_key == "maximized") { | 581 | } else if (str_key == "maximized") { |
@@ -1009,6 +1036,31 @@ void Remember::save() { | |||
1009 | if (a.focusnewwindow_remember) { | 1036 | if (a.focusnewwindow_remember) { |
1010 | apps_file << " [FocusNewWindow]\t{" << ((a.focusnewwindow)?"yes":"no") << "}" << endl; | 1037 | apps_file << " [FocusNewWindow]\t{" << ((a.focusnewwindow)?"yes":"no") << "}" << endl; |
1011 | } | 1038 | } |
1039 | if (a.focusprotection_remember) { | ||
1040 | apps_file << " [FocusProtection]\t{"; | ||
1041 | if (a.focusprotection == Focus::NoProtection) { | ||
1042 | apps_file << "none"; | ||
1043 | } else { | ||
1044 | bool b = false; | ||
1045 | if (a.focusprotection & Focus::Gain) { | ||
1046 | apps_file << (b?",":"") << "gain"; | ||
1047 | b = true; | ||
1048 | } | ||
1049 | if (a.focusprotection & Focus::Refuse) { | ||
1050 | apps_file << (b?",":"") << "refuse"; | ||
1051 | b = true; | ||
1052 | } | ||
1053 | if (a.focusprotection & Focus::Lock) { | ||
1054 | apps_file << (b?",":"") << "lock"; | ||
1055 | b = true; | ||
1056 | } | ||
1057 | if (a.focusprotection & Focus::Deny) { | ||
1058 | apps_file << (b?",":"") << "deny"; | ||
1059 | b = true; | ||
1060 | } | ||
1061 | } | ||
1062 | apps_file << "}" << endl; | ||
1063 | } | ||
1012 | if (a.minimizedstate_remember) { | 1064 | if (a.minimizedstate_remember) { |
1013 | apps_file << " [Minimized]\t{" << ((a.minimizedstate)?"yes":"no") << "}" << endl; | 1065 | apps_file << " [Minimized]\t{" << ((a.minimizedstate)?"yes":"no") << "}" << endl; |
1014 | } | 1066 | } |
@@ -1083,6 +1135,9 @@ bool Remember::isRemembered(WinClient &winclient, Attribute attrib) { | |||
1083 | case REM_FOCUSNEWWINDOW: | 1135 | case REM_FOCUSNEWWINDOW: |
1084 | return app->focusnewwindow_remember; | 1136 | return app->focusnewwindow_remember; |
1085 | break; | 1137 | break; |
1138 | case REM_FOCUSPROTECTION: | ||
1139 | return app->focusprotection_remember; | ||
1140 | break; | ||
1086 | case REM_MINIMIZEDSTATE: | 1141 | case REM_MINIMIZEDSTATE: |
1087 | return app->minimizedstate_remember; | 1142 | return app->minimizedstate_remember; |
1088 | break; | 1143 | break; |
@@ -1166,6 +1221,9 @@ void Remember::rememberAttrib(WinClient &winclient, Attribute attrib) { | |||
1166 | case REM_FOCUSNEWWINDOW: | 1221 | case REM_FOCUSNEWWINDOW: |
1167 | app->rememberFocusNewWindow(win->isFocusNew()); | 1222 | app->rememberFocusNewWindow(win->isFocusNew()); |
1168 | break; | 1223 | break; |
1224 | case REM_FOCUSPROTECTION: | ||
1225 | app->rememberFocusProtection(win->focusProtection()); | ||
1226 | break; | ||
1169 | case REM_MINIMIZEDSTATE: | 1227 | case REM_MINIMIZEDSTATE: |
1170 | app->rememberMinimizedstate(win->isIconic()); | 1228 | app->rememberMinimizedstate(win->isIconic()); |
1171 | break; | 1229 | break; |
@@ -1229,6 +1287,9 @@ void Remember::forgetAttrib(WinClient &winclient, Attribute attrib) { | |||
1229 | case REM_FOCUSNEWWINDOW: | 1287 | case REM_FOCUSNEWWINDOW: |
1230 | app->forgetFocusNewWindow(); | 1288 | app->forgetFocusNewWindow(); |
1231 | break; | 1289 | break; |
1290 | case REM_FOCUSPROTECTION: | ||
1291 | app->forgetFocusProtection(); | ||
1292 | break; | ||
1232 | case REM_MINIMIZEDSTATE: | 1293 | case REM_MINIMIZEDSTATE: |
1233 | app->forgetMinimizedstate(); | 1294 | app->forgetMinimizedstate(); |
1234 | break; | 1295 | break; |
@@ -1355,6 +1416,10 @@ void Remember::setupFrame(FluxboxWindow &win) { | |||
1355 | if (app->focusnewwindow_remember) | 1416 | if (app->focusnewwindow_remember) |
1356 | win.setFocusNew(app->focusnewwindow); | 1417 | win.setFocusNew(app->focusnewwindow); |
1357 | 1418 | ||
1419 | if (app->focusprotection_remember) { | ||
1420 | win.setFocusProtection(app->focusprotection); | ||
1421 | } | ||
1422 | |||
1358 | if (app->minimizedstate_remember) { | 1423 | if (app->minimizedstate_remember) { |
1359 | // if inconsistent... | 1424 | // if inconsistent... |
1360 | // this one doesn't actually work, but I can't imagine needing it | 1425 | // this one doesn't actually work, but I can't imagine needing it |
diff --git a/src/Remember.hh b/src/Remember.hh index a6a980e..59fb1d3 100644 --- a/src/Remember.hh +++ b/src/Remember.hh | |||
@@ -75,6 +75,7 @@ public: | |||
75 | REM_MAXIMIZEDSTATE, | 75 | REM_MAXIMIZEDSTATE, |
76 | REM_FULLSCREENSTATE, | 76 | REM_FULLSCREENSTATE, |
77 | REM_FOCUSNEWWINDOW, | 77 | REM_FOCUSNEWWINDOW, |
78 | REM_FOCUSPROTECTION, | ||
78 | REM_LASTATTRIB // not actually used | 79 | REM_LASTATTRIB // not actually used |
79 | }; | 80 | }; |
80 | 81 | ||
@@ -87,7 +88,6 @@ public: | |||
87 | }; | 88 | }; |
88 | 89 | ||
89 | 90 | ||
90 | |||
91 | // a "pattern" to the relevant app | 91 | // a "pattern" to the relevant app |
92 | // each app exists ONLY for that pattern. | 92 | // each app exists ONLY for that pattern. |
93 | // And we need to keep a list of pairs as we want to keep the | 93 | // And we need to keep a list of pairs as we want to keep the |
diff --git a/src/Window.cc b/src/Window.cc index ac76aee..929cec8 100644 --- a/src/Window.cc +++ b/src/Window.cc | |||
@@ -291,6 +291,7 @@ FluxboxWindow::FluxboxWindow(WinClient &client): | |||
291 | m_client(&client), | 291 | m_client(&client), |
292 | m_toggled_decos(false), | 292 | m_toggled_decos(false), |
293 | m_focus_new(BoolAcc(screen().focusControl(), &FocusControl::focusNew)), | 293 | m_focus_new(BoolAcc(screen().focusControl(), &FocusControl::focusNew)), |
294 | m_focus_protection(Focus::NoProtection), | ||
294 | m_mouse_focus(BoolAcc(screen().focusControl(), &FocusControl::isMouseFocus)), | 295 | m_mouse_focus(BoolAcc(screen().focusControl(), &FocusControl::isMouseFocus)), |
295 | m_click_focus(true), | 296 | m_click_focus(true), |
296 | m_last_button_x(0), m_last_button_y(0), | 297 | m_last_button_x(0), m_last_button_y(0), |
@@ -563,7 +564,10 @@ void FluxboxWindow::init() { | |||
563 | // check if we should prevent this window from gaining focus | 564 | // check if we should prevent this window from gaining focus |
564 | m_focused = false; // deiconify sets this | 565 | m_focused = false; // deiconify sets this |
565 | if (!Fluxbox::instance()->isStartup() && m_focus_new) { | 566 | if (!Fluxbox::instance()->isStartup() && m_focus_new) { |
567 | Focus::Protection fp = m_focus_protection; | ||
568 | m_focus_protection &= ~Focus::Deny; // new windows run as "Refuse" | ||
566 | m_focused = focusRequestFromClient(*m_client); | 569 | m_focused = focusRequestFromClient(*m_client); |
570 | m_focus_protection = fp; | ||
567 | if (!m_focused) | 571 | if (!m_focused) |
568 | lower(); | 572 | lower(); |
569 | } | 573 | } |
@@ -2025,7 +2029,10 @@ void FluxboxWindow::mapRequestEvent(XMapRequestEvent &re) { | |||
2025 | 2029 | ||
2026 | if (m_focus_new) { | 2030 | if (m_focus_new) { |
2027 | m_focused = false; // deiconify sets this | 2031 | m_focused = false; // deiconify sets this |
2032 | Focus::Protection fp = m_focus_protection; | ||
2033 | m_focus_protection &= ~Focus::Deny; // goes by "Refuse" | ||
2028 | m_focused = focusRequestFromClient(*client); | 2034 | m_focused = focusRequestFromClient(*client); |
2035 | m_focus_protection = fp; | ||
2029 | if (!m_focused) | 2036 | if (!m_focused) |
2030 | lower(); | 2037 | lower(); |
2031 | } | 2038 | } |
@@ -2041,9 +2048,13 @@ bool FluxboxWindow::focusRequestFromClient(WinClient &from) { | |||
2041 | 2048 | ||
2042 | FluxboxWindow *cur = FocusControl::focusedFbWindow(); | 2049 | FluxboxWindow *cur = FocusControl::focusedFbWindow(); |
2043 | WinClient *client = FocusControl::focusedWindow(); | 2050 | WinClient *client = FocusControl::focusedWindow(); |
2044 | if (cur && getRootTransientFor(&from) != getRootTransientFor(client)) | 2051 | if ((from.fbwindow() && (from.fbwindow()->focusProtection() & Focus::Deny)) || |
2052 | (cur && (cur->focusProtection() & Focus::Lock))) { | ||
2053 | ret = false; | ||
2054 | } else if (cur && getRootTransientFor(&from) != getRootTransientFor(client)) { | ||
2045 | ret = !(cur->isFullscreen() && getOnHead() == cur->getOnHead()) && | 2055 | ret = !(cur->isFullscreen() && getOnHead() == cur->getOnHead()) && |
2046 | !cur->isTyping(); | 2056 | !cur->isTyping(); |
2057 | } | ||
2047 | 2058 | ||
2048 | if (!ret) | 2059 | if (!ret) |
2049 | Fluxbox::instance()->attentionHandler().addAttention(from); | 2060 | Fluxbox::instance()->attentionHandler().addAttention(from); |
diff --git a/src/Window.hh b/src/Window.hh index c04676a..706f8ed 100644 --- a/src/Window.hh +++ b/src/Window.hh | |||
@@ -56,6 +56,18 @@ class ImageControl; | |||
56 | class Layer; | 56 | class Layer; |
57 | } | 57 | } |
58 | 58 | ||
59 | namespace Focus { | ||
60 | enum { | ||
61 | NoProtection = 0, | ||
62 | Gain = 1, | ||
63 | Refuse = 2, | ||
64 | Lock = 4, | ||
65 | Deny = 8 | ||
66 | }; | ||
67 | typedef unsigned int Protection; | ||
68 | } | ||
69 | |||
70 | |||
59 | /// Creates the window frame and handles any window event for it | 71 | /// Creates the window frame and handles any window event for it |
60 | class FluxboxWindow: public Focusable, | 72 | class FluxboxWindow: public Focusable, |
61 | public FbTk::EventHandler, | 73 | public FbTk::EventHandler, |
@@ -256,6 +268,8 @@ public: | |||
256 | void setIconHidden(bool value); | 268 | void setIconHidden(bool value); |
257 | /// sets whether or not the window normally gets focus when mapped | 269 | /// sets whether or not the window normally gets focus when mapped |
258 | void setFocusNew(bool value) { m_focus_new = value; } | 270 | void setFocusNew(bool value) { m_focus_new = value; } |
271 | /// sets how to protect the focus on or against this window | ||
272 | void setFocusProtection(Focus::Protection value) { m_focus_protection = value; } | ||
259 | /// sets whether or not the window gets focused with mouse | 273 | /// sets whether or not the window gets focused with mouse |
260 | void setMouseFocus(bool value) { m_mouse_focus = value; } | 274 | void setMouseFocus(bool value) { m_mouse_focus = value; } |
261 | /// sets whether or not the window gets focused with click | 275 | /// sets whether or not the window gets focused with click |
@@ -384,6 +398,7 @@ public: | |||
384 | bool isMoveable() const { return functions.move; } | 398 | bool isMoveable() const { return functions.move; } |
385 | bool isStuck() const { return m_state.stuck; } | 399 | bool isStuck() const { return m_state.stuck; } |
386 | bool isFocusNew() const { return m_focus_new; } | 400 | bool isFocusNew() const { return m_focus_new; } |
401 | Focus::Protection focusProtection() const { return m_focus_protection; } | ||
387 | bool hasTitlebar() const { return decorations.titlebar; } | 402 | bool hasTitlebar() const { return decorations.titlebar; } |
388 | bool isMoving() const { return moving; } | 403 | bool isMoving() const { return moving; } |
389 | bool isResizing() const { return resizing; } | 404 | bool isResizing() const { return resizing; } |
@@ -572,6 +587,8 @@ private: | |||
572 | typedef FbTk::ConstObjectAccessor<bool, FocusControl> BoolAcc; | 587 | typedef FbTk::ConstObjectAccessor<bool, FocusControl> BoolAcc; |
573 | /// if the window is normally focused when mapped | 588 | /// if the window is normally focused when mapped |
574 | FbTk::DefaultValue<bool, BoolAcc> m_focus_new; | 589 | FbTk::DefaultValue<bool, BoolAcc> m_focus_new; |
590 | /// special focus permissions | ||
591 | Focus::Protection m_focus_protection; | ||
575 | /// if the window is focused with EnterNotify | 592 | /// if the window is focused with EnterNotify |
576 | FbTk::DefaultValue<bool, BoolAcc> m_mouse_focus; | 593 | FbTk::DefaultValue<bool, BoolAcc> m_mouse_focus; |
577 | bool m_click_focus; ///< if the window is focused by clicking | 594 | bool m_click_focus; ///< if the window is focused by clicking |