aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/FocusControl.cc7
-rw-r--r--src/Remember.cc65
-rw-r--r--src/Remember.hh2
-rw-r--r--src/Window.cc13
-rw-r--r--src/Window.hh17
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;
56class Layer; 56class Layer;
57} 57}
58 58
59namespace 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
60class FluxboxWindow: public Focusable, 72class 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