aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrathnor <rathnor>2002-09-12 14:55:11 (GMT)
committerrathnor <rathnor>2002-09-12 14:55:11 (GMT)
commite54676573689d353bf53a4d6225ba1206ddf10fa (patch)
tree1f7dcc90b3613f46f469dcece4acf5ebfbe81221
parent8a728b46fd05b872b5daf9632af478f1c098dd4f (diff)
downloadfluxbox-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.cc56
-rw-r--r--src/Tab.cc23
-rw-r--r--src/Window.cc27
-rw-r--r--src/Workspace.cc10
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 -----------
diff --git a/src/Tab.cc b/src/Tab.cc
index 8752c14..b39ca1c 100644
--- a/src/Tab.cc
+++ b/src/Tab.cc
@@ -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() {
283void Tab::stick() { 283void 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();