diff options
author | rathnor <rathnor> | 2002-09-12 14:55:11 (GMT) |
---|---|---|
committer | rathnor <rathnor> | 2002-09-12 14:55:11 (GMT) |
commit | e54676573689d353bf53a4d6225ba1206ddf10fa (patch) | |
tree | 1f7dcc90b3613f46f469dcece4acf5ebfbe81221 | |
parent | 8a728b46fd05b872b5daf9632af478f1c098dd4f (diff) | |
download | fluxbox-e54676573689d353bf53a4d6225ba1206ddf10fa.zip fluxbox-e54676573689d353bf53a4d6225ba1206ddf10fa.tar.bz2 |
Fixes to sticky window + focus handling. Particularly for
next/prevFocus crashes. Also, sticky windows are now always reassociated
to the active workspace.
-rw-r--r-- | src/Screen.cc | 56 | ||||
-rw-r--r-- | src/Tab.cc | 23 | ||||
-rw-r--r-- | src/Window.cc | 27 | ||||
-rw-r--r-- | src/Workspace.cc | 10 |
4 files changed, 69 insertions, 47 deletions
diff --git a/src/Screen.cc b/src/Screen.cc index ab388ab..e25de0e 100644 --- a/src/Screen.cc +++ b/src/Screen.cc | |||
@@ -22,7 +22,7 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: Screen.cc,v 1.68 2002/09/10 10:59:57 fluxgen Exp $ | 25 | // $Id: Screen.cc,v 1.69 2002/09/12 14:55:11 rathnor Exp $ |
26 | 26 | ||
27 | //use GNU extensions | 27 | //use GNU extensions |
28 | #ifndef _GNU_SOURCE | 28 | #ifndef _GNU_SOURCE |
@@ -784,6 +784,15 @@ void BScreen::changeWorkspaceID(unsigned int id) { | |||
784 | focused->pauseMoving(); | 784 | focused->pauseMoving(); |
785 | } | 785 | } |
786 | 786 | ||
787 | Workspace *wksp = getCurrentWorkspace(); | ||
788 | Workspace::Windows wins = wksp->getWindowList(); | ||
789 | Workspace::Windows::iterator it = wins.begin(); | ||
790 | for (; it != wins.end(); ++it) { | ||
791 | if ((*it)->isStuck()) { | ||
792 | reassociateGroup(*it,id,true); | ||
793 | } | ||
794 | } | ||
795 | |||
787 | current_workspace->hideAll(); | 796 | current_workspace->hideAll(); |
788 | 797 | ||
789 | workspacemenu->setItemSelected(current_workspace->workspaceID() + 2, false); | 798 | workspacemenu->setItemSelected(current_workspace->workspaceID() + 2, false); |
@@ -805,6 +814,8 @@ void BScreen::changeWorkspaceID(unsigned int id) { | |||
805 | if (*resource.focus_last && current_workspace->getLastFocusedWindow() && | 814 | if (*resource.focus_last && current_workspace->getLastFocusedWindow() && |
806 | !(focused && focused->isMoving())) { | 815 | !(focused && focused->isMoving())) { |
807 | current_workspace->getLastFocusedWindow()->setInputFocus(); | 816 | current_workspace->getLastFocusedWindow()->setInputFocus(); |
817 | } else if (focused && focused->isStuck()) { | ||
818 | focused->setInputFocus(); | ||
808 | } | 819 | } |
809 | 820 | ||
810 | if (focused && focused->isMoving()) { | 821 | if (focused && focused->isMoving()) { |
@@ -1110,7 +1121,7 @@ void BScreen::nextFocus(int opts) { | |||
1110 | int focused_window_number = -1; | 1121 | int focused_window_number = -1; |
1111 | FluxboxWindow *focused = fluxbox->getFocusedWindow(); | 1122 | FluxboxWindow *focused = fluxbox->getFocusedWindow(); |
1112 | const int num_windows = getCurrentWorkspace()->getCount(); | 1123 | const int num_windows = getCurrentWorkspace()->getCount(); |
1113 | 1124 | ||
1114 | if (focused != 0) { | 1125 | if (focused != 0) { |
1115 | if (focused->getScreen()->getScreenNumber() == | 1126 | if (focused->getScreen()->getScreenNumber() == |
1116 | getScreenNumber()) { | 1127 | getScreenNumber()) { |
@@ -1119,14 +1130,17 @@ void BScreen::nextFocus(int opts) { | |||
1119 | } | 1130 | } |
1120 | } | 1131 | } |
1121 | 1132 | ||
1122 | if (num_windows > 1 && have_focused) { | 1133 | if (num_windows >= 1) { |
1123 | Workspace *wksp = getCurrentWorkspace(); | 1134 | Workspace *wksp = getCurrentWorkspace(); |
1124 | Workspace::Windows &wins = wksp->getWindowList(); | 1135 | Workspace::Windows &wins = wksp->getWindowList(); |
1125 | Workspace::Windows::iterator it = wins.begin(); | 1136 | Workspace::Windows::iterator it = wins.begin(); |
1126 | 1137 | ||
1127 | for (; *it != focused; ++it) //get focused window iterator | 1138 | if (!have_focused) { |
1128 | continue; | 1139 | focused = *it; |
1129 | 1140 | } else { | |
1141 | for (; *it != focused; ++it) //get focused window iterator | ||
1142 | continue; | ||
1143 | } | ||
1130 | do { | 1144 | do { |
1131 | ++it; | 1145 | ++it; |
1132 | if (it == wins.end()) | 1146 | if (it == wins.end()) |
@@ -1139,11 +1153,6 @@ void BScreen::nextFocus(int opts) { | |||
1139 | if (*it != focused && it != wins.end()) | 1153 | if (*it != focused && it != wins.end()) |
1140 | wksp->raiseWindow(*it); | 1154 | wksp->raiseWindow(*it); |
1141 | 1155 | ||
1142 | } else if (num_windows >= 1) { | ||
1143 | FluxboxWindow *next = current_workspace->getWindow(0); | ||
1144 | //don't raise next window if input focus fails | ||
1145 | if (next->setInputFocus()) | ||
1146 | current_workspace->raiseWindow(next); | ||
1147 | } | 1156 | } |
1148 | 1157 | ||
1149 | } | 1158 | } |
@@ -1163,28 +1172,31 @@ void BScreen::prevFocus(int opts) { | |||
1163 | } | 1172 | } |
1164 | } | 1173 | } |
1165 | 1174 | ||
1166 | if (num_windows > 1 && have_focused) { | 1175 | if (num_windows >= 1) { |
1167 | Workspace *wksp = getCurrentWorkspace(); | 1176 | Workspace *wksp = getCurrentWorkspace(); |
1168 | Workspace::Windows wins = wksp->getWindowList(); | 1177 | Workspace::Windows &wins = wksp->getWindowList(); |
1169 | Workspace::Windows::iterator it = wins.begin(); | 1178 | Workspace::Windows::iterator it = wins.begin(); |
1170 | for (; *it != focused; ++it); | 1179 | |
1180 | if (!have_focused) { | ||
1181 | focused = *it; | ||
1182 | } else { | ||
1183 | for (; *it != focused; ++it) //get focused window iterator | ||
1184 | continue; | ||
1185 | } | ||
1186 | |||
1171 | do { | 1187 | do { |
1172 | if (it == wins.begin()) | 1188 | if (it == wins.begin()) |
1173 | it = wins.end(); | 1189 | it = wins.end(); |
1174 | --it; | 1190 | --it; |
1175 | // see if the window should be skipped | 1191 | // see if the window should be skipped |
1176 | if (! (doSkipWindow(*it, opts) || !(*it)->setInputFocus()) ) | 1192 | if (! (doSkipWindow(*it, opts) || !(*it)->setInputFocus()) ) |
1177 | break; | 1193 | break; |
1178 | } while (*it != focused); | 1194 | } while (*it != focused); |
1179 | if (*it != focused) | 1195 | |
1196 | if (*it != focused && it != wins.end()) | ||
1180 | wksp->raiseWindow(*it); | 1197 | wksp->raiseWindow(*it); |
1181 | } else if (num_windows >= 1) { | ||
1182 | FluxboxWindow *next = current_workspace->getWindow(0); | ||
1183 | //don't raise next window if input focus fails | ||
1184 | if (next->setInputFocus()) | ||
1185 | current_workspace->raiseWindow(next); | ||
1186 | } | ||
1187 | 1198 | ||
1199 | } | ||
1188 | } | 1200 | } |
1189 | 1201 | ||
1190 | //--------- raiseFocus ----------- | 1202 | //--------- raiseFocus ----------- |
@@ -19,7 +19,7 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | // $Id: Tab.cc,v 1.32 2002/09/08 19:41:59 fluxgen Exp $ | 22 | // $Id: Tab.cc,v 1.33 2002/09/12 14:55:11 rathnor Exp $ |
23 | 23 | ||
24 | #include "Tab.hh" | 24 | #include "Tab.hh" |
25 | 25 | ||
@@ -283,20 +283,24 @@ void Tab::withdraw() { | |||
283 | void Tab::stick() { | 283 | void Tab::stick() { |
284 | Tab *tab; | 284 | Tab *tab; |
285 | 285 | ||
286 | bool wasstuck = m_win->isStuck(); | ||
287 | |||
286 | //now do stick for all windows in the list | 288 | //now do stick for all windows in the list |
287 | for (tab = getFirst(this); tab != 0; tab = tab->m_next) { | 289 | for (tab = getFirst(this); tab != 0; tab = tab->m_next) { |
288 | FluxboxWindow *win = tab->m_win; //just for convenience | 290 | FluxboxWindow *win = tab->m_win; //just for convenience |
289 | if (win->isStuck()) { | 291 | if (wasstuck) { |
290 | win->blackbox_attrib.flags ^= BaseDisplay::ATTRIB_OMNIPRESENT; | 292 | win->blackbox_attrib.flags ^= BaseDisplay::ATTRIB_OMNIPRESENT; |
291 | win->blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_OMNIPRESENT; | 293 | win->blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_OMNIPRESENT; |
292 | win->stuck = false; | 294 | win->stuck = false; |
293 | if (!win->isIconic()) { | ||
294 | BScreen *screen = win->getScreen(); | ||
295 | screen->reassociateWindow(win, screen->getCurrentWorkspace()->workspaceID(), true); | ||
296 | } | ||
297 | 295 | ||
298 | } else { | 296 | } else { |
299 | win->stuck = true; | 297 | win->stuck = true; |
298 | BScreen *screen = win->getScreen(); | ||
299 | if (!win->isIconic() && !(win->getWorkspaceNumber() != | ||
300 | screen->getCurrentWorkspaceID())) { | ||
301 | screen->reassociateWindow(win, screen->getCurrentWorkspaceID(), true); | ||
302 | } | ||
303 | |||
300 | win->blackbox_attrib.flags |= BaseDisplay::ATTRIB_OMNIPRESENT; | 304 | win->blackbox_attrib.flags |= BaseDisplay::ATTRIB_OMNIPRESENT; |
301 | win->blackbox_attrib.attrib |= BaseDisplay::ATTRIB_OMNIPRESENT; | 305 | win->blackbox_attrib.attrib |= BaseDisplay::ATTRIB_OMNIPRESENT; |
302 | } | 306 | } |
@@ -936,9 +940,10 @@ void Tab::insert(Tab *tab) { | |||
936 | for (; last->m_next!=0; last=last->m_next); | 940 | for (; last->m_next!=0; last=last->m_next); |
937 | //do sticky before we connect it to the chain | 941 | //do sticky before we connect it to the chain |
938 | //sticky bit on window | 942 | //sticky bit on window |
939 | if (m_win->isStuck() && !tab->m_win->isStuck() || | 943 | if (m_win->isStuck() != tab->m_win->isStuck()) { |
940 | !m_win->isStuck() && tab->m_win->isStuck()) | 944 | tab->m_win->stuck = !m_win->stuck; // it will toggle |
941 | tab->m_win->stick(); //this will set all the m_wins in the list | 945 | tab->stick(); //this will set all the m_wins in the list |
946 | } | ||
942 | 947 | ||
943 | //connect the tab to this chain | 948 | //connect the tab to this chain |
944 | 949 | ||
diff --git a/src/Window.cc b/src/Window.cc index 8ec14e3..019ccb4 100644 --- a/src/Window.cc +++ b/src/Window.cc | |||
@@ -22,7 +22,7 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: Window.cc,v 1.85 2002/09/11 15:12:40 fluxgen Exp $ | 25 | // $Id: Window.cc,v 1.86 2002/09/12 14:55:11 rathnor Exp $ |
26 | 26 | ||
27 | #include "Window.hh" | 27 | #include "Window.hh" |
28 | 28 | ||
@@ -100,7 +100,7 @@ tab(0) { | |||
100 | frame.utitle = frame.ftitle = frame.uhandle = frame.fhandle = None; | 100 | frame.utitle = frame.ftitle = frame.uhandle = frame.fhandle = None; |
101 | frame.ulabel = frame.flabel = frame.ubutton = frame.fbutton = None; | 101 | frame.ulabel = frame.flabel = frame.ubutton = frame.fbutton = None; |
102 | frame.pbutton = frame.ugrip = frame.fgrip = None; | 102 | frame.pbutton = frame.ugrip = frame.fgrip = None; |
103 | 103 | ||
104 | //get decorations | 104 | //get decorations |
105 | vector<Fluxbox::Titlebar> dir = fluxbox->getTitlebarLeft(); | 105 | vector<Fluxbox::Titlebar> dir = fluxbox->getTitlebarLeft(); |
106 | for (char c=0; c<2; c++) { | 106 | for (char c=0; c<2; c++) { |
@@ -164,7 +164,7 @@ tab(0) { | |||
164 | fluxbox->ungrab(); | 164 | fluxbox->ungrab(); |
165 | return; | 165 | return; |
166 | } | 166 | } |
167 | 167 | ||
168 | image_ctrl = screen->getImageControl(); | 168 | image_ctrl = screen->getImageControl(); |
169 | 169 | ||
170 | client.x = wattrib.x; | 170 | client.x = wattrib.x; |
@@ -186,7 +186,6 @@ tab(0) { | |||
186 | getWMProtocols(); | 186 | getWMProtocols(); |
187 | getWMHints(); | 187 | getWMHints(); |
188 | getWMNormalHints(); | 188 | getWMNormalHints(); |
189 | |||
190 | #ifdef SLIT | 189 | #ifdef SLIT |
191 | 190 | ||
192 | if (client.initial_state == WithdrawnState) { | 191 | if (client.initial_state == WithdrawnState) { |
@@ -219,7 +218,7 @@ tab(0) { | |||
219 | } | 218 | } |
220 | 219 | ||
221 | upsize(); | 220 | upsize(); |
222 | 221 | ||
223 | bool place_window = true; | 222 | bool place_window = true; |
224 | if (fluxbox->isStartup() || transient || | 223 | if (fluxbox->isStartup() || transient || |
225 | client.normal_hint_flags & (PPosition|USPosition)) { | 224 | client.normal_hint_flags & (PPosition|USPosition)) { |
@@ -319,11 +318,16 @@ tab(0) { | |||
319 | int m = maximized; | 318 | int m = maximized; |
320 | maximized = false; | 319 | maximized = false; |
321 | maximize(m); | 320 | maximize(m); |
321 | } | ||
322 | |||
323 | if (stuck) { | ||
324 | stuck = false; | ||
325 | stick(); | ||
326 | deiconify(); //omnipresent, so show it | ||
322 | } | 327 | } |
323 | 328 | ||
324 | setFocusFlag(false); | 329 | setFocusFlag(false); |
325 | 330 | ||
326 | |||
327 | #ifdef DEBUG | 331 | #ifdef DEBUG |
328 | fprintf(stderr, "%s(%d): FluxboxWindow(this=%p)\n", __FILE__, __LINE__, this); | 332 | fprintf(stderr, "%s(%d): FluxboxWindow(this=%p)\n", __FILE__, __LINE__, this); |
329 | #endif // DEBUG | 333 | #endif // DEBUG |
@@ -1172,7 +1176,7 @@ void FluxboxWindow::getWMProtocols() { | |||
1172 | Atom *proto; | 1176 | Atom *proto; |
1173 | int num_return = 0; | 1177 | int num_return = 0; |
1174 | Fluxbox *fluxbox = Fluxbox::instance(); | 1178 | Fluxbox *fluxbox = Fluxbox::instance(); |
1175 | 1179 | ||
1176 | if (XGetWMProtocols(display, client.window, &proto, &num_return)) { | 1180 | if (XGetWMProtocols(display, client.window, &proto, &num_return)) { |
1177 | for (int i = 0; i < num_return; ++i) { | 1181 | for (int i = 0; i < num_return; ++i) { |
1178 | if (proto[i] == fluxbox->getWMDeleteAtom()) | 1182 | if (proto[i] == fluxbox->getWMDeleteAtom()) |
@@ -2062,13 +2066,12 @@ void FluxboxWindow::stick() { | |||
2062 | 2066 | ||
2063 | stuck = false; | 2067 | stuck = false; |
2064 | 2068 | ||
2065 | if (! iconic) | ||
2066 | screen->reassociateWindow(this, screen->getCurrentWorkspace()->workspaceID(), true); | ||
2067 | |||
2068 | |||
2069 | } else { | 2069 | } else { |
2070 | stuck = true; | 2070 | stuck = true; |
2071 | 2071 | if (screen->getCurrentWorkspaceID() != workspace_number) { | |
2072 | screen->reassociateWindow(this,screen->getCurrentWorkspaceID(), true); | ||
2073 | } | ||
2074 | |||
2072 | blackbox_attrib.flags |= BaseDisplay::ATTRIB_OMNIPRESENT; | 2075 | blackbox_attrib.flags |= BaseDisplay::ATTRIB_OMNIPRESENT; |
2073 | blackbox_attrib.attrib |= BaseDisplay::ATTRIB_OMNIPRESENT; | 2076 | blackbox_attrib.attrib |= BaseDisplay::ATTRIB_OMNIPRESENT; |
2074 | 2077 | ||
diff --git a/src/Workspace.cc b/src/Workspace.cc index 653907c..7d87a20 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc | |||
@@ -22,7 +22,7 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: Workspace.cc,v 1.29 2002/09/10 11:03:58 fluxgen Exp $ | 25 | // $Id: Workspace.cc,v 1.30 2002/09/12 14:55:11 rathnor Exp $ |
26 | 26 | ||
27 | #include "Workspace.hh" | 27 | #include "Workspace.hh" |
28 | 28 | ||
@@ -137,7 +137,8 @@ int Workspace::addWindow(FluxboxWindow *w, bool place) { | |||
137 | //update menugraphics | 137 | //update menugraphics |
138 | m_clientmenu.update(); | 138 | m_clientmenu.update(); |
139 | 139 | ||
140 | screen->updateNetizenWindowAdd(w->getClientWindow(), m_id); | 140 | if (!w->isStuck()) |
141 | screen->updateNetizenWindowAdd(w->getClientWindow(), m_id); | ||
141 | 142 | ||
142 | raiseWindow(w); | 143 | raiseWindow(w); |
143 | 144 | ||
@@ -191,8 +192,9 @@ int Workspace::removeWindow(FluxboxWindow *w) { | |||
191 | 192 | ||
192 | m_clientmenu.remove(w->getWindowNumber()); | 193 | m_clientmenu.remove(w->getWindowNumber()); |
193 | m_clientmenu.update(); | 194 | m_clientmenu.update(); |
194 | 195 | ||
195 | screen->updateNetizenWindowDel(w->getClientWindow()); | 196 | if (!w->isStuck()) |
197 | screen->updateNetizenWindowDel(w->getClientWindow()); | ||
196 | 198 | ||
197 | { | 199 | { |
198 | Windows::iterator it = windowList.begin(); | 200 | Windows::iterator it = windowList.begin(); |