From e54676573689d353bf53a4d6225ba1206ddf10fa Mon Sep 17 00:00:00 2001 From: rathnor Date: Thu, 12 Sep 2002 14:55:11 +0000 Subject: Fixes to sticky window + focus handling. Particularly for next/prevFocus crashes. Also, sticky windows are now always reassociated to the active workspace. --- src/Screen.cc | 56 ++++++++++++++++++++++++++++++++++---------------------- src/Tab.cc | 23 ++++++++++++++--------- src/Window.cc | 27 +++++++++++++++------------ 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 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.cc,v 1.68 2002/09/10 10:59:57 fluxgen Exp $ +// $Id: Screen.cc,v 1.69 2002/09/12 14:55:11 rathnor Exp $ //use GNU extensions #ifndef _GNU_SOURCE @@ -784,6 +784,15 @@ void BScreen::changeWorkspaceID(unsigned int id) { focused->pauseMoving(); } + Workspace *wksp = getCurrentWorkspace(); + Workspace::Windows wins = wksp->getWindowList(); + Workspace::Windows::iterator it = wins.begin(); + for (; it != wins.end(); ++it) { + if ((*it)->isStuck()) { + reassociateGroup(*it,id,true); + } + } + current_workspace->hideAll(); workspacemenu->setItemSelected(current_workspace->workspaceID() + 2, false); @@ -805,6 +814,8 @@ void BScreen::changeWorkspaceID(unsigned int id) { if (*resource.focus_last && current_workspace->getLastFocusedWindow() && !(focused && focused->isMoving())) { current_workspace->getLastFocusedWindow()->setInputFocus(); + } else if (focused && focused->isStuck()) { + focused->setInputFocus(); } if (focused && focused->isMoving()) { @@ -1110,7 +1121,7 @@ void BScreen::nextFocus(int opts) { int focused_window_number = -1; FluxboxWindow *focused = fluxbox->getFocusedWindow(); const int num_windows = getCurrentWorkspace()->getCount(); - + if (focused != 0) { if (focused->getScreen()->getScreenNumber() == getScreenNumber()) { @@ -1119,14 +1130,17 @@ void BScreen::nextFocus(int opts) { } } - if (num_windows > 1 && have_focused) { + if (num_windows >= 1) { Workspace *wksp = getCurrentWorkspace(); Workspace::Windows &wins = wksp->getWindowList(); Workspace::Windows::iterator it = wins.begin(); - for (; *it != focused; ++it) //get focused window iterator - continue; - + if (!have_focused) { + focused = *it; + } else { + for (; *it != focused; ++it) //get focused window iterator + continue; + } do { ++it; if (it == wins.end()) @@ -1139,11 +1153,6 @@ void BScreen::nextFocus(int opts) { if (*it != focused && it != wins.end()) wksp->raiseWindow(*it); - } else if (num_windows >= 1) { - FluxboxWindow *next = current_workspace->getWindow(0); - //don't raise next window if input focus fails - if (next->setInputFocus()) - current_workspace->raiseWindow(next); } } @@ -1163,28 +1172,31 @@ void BScreen::prevFocus(int opts) { } } - if (num_windows > 1 && have_focused) { + if (num_windows >= 1) { Workspace *wksp = getCurrentWorkspace(); - Workspace::Windows wins = wksp->getWindowList(); + Workspace::Windows &wins = wksp->getWindowList(); Workspace::Windows::iterator it = wins.begin(); - for (; *it != focused; ++it); + + if (!have_focused) { + focused = *it; + } else { + for (; *it != focused; ++it) //get focused window iterator + continue; + } + do { if (it == wins.begin()) it = wins.end(); --it; // see if the window should be skipped - if (! (doSkipWindow(*it, opts) || !(*it)->setInputFocus()) ) + if (! (doSkipWindow(*it, opts) || !(*it)->setInputFocus()) ) break; } while (*it != focused); - if (*it != focused) + + if (*it != focused && it != wins.end()) wksp->raiseWindow(*it); - } else if (num_windows >= 1) { - FluxboxWindow *next = current_workspace->getWindow(0); - //don't raise next window if input focus fails - if (next->setInputFocus()) - current_workspace->raiseWindow(next); - } + } } //--------- 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 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Tab.cc,v 1.32 2002/09/08 19:41:59 fluxgen Exp $ +// $Id: Tab.cc,v 1.33 2002/09/12 14:55:11 rathnor Exp $ #include "Tab.hh" @@ -283,20 +283,24 @@ void Tab::withdraw() { void Tab::stick() { Tab *tab; + bool wasstuck = m_win->isStuck(); + //now do stick for all windows in the list for (tab = getFirst(this); tab != 0; tab = tab->m_next) { FluxboxWindow *win = tab->m_win; //just for convenience - if (win->isStuck()) { + if (wasstuck) { win->blackbox_attrib.flags ^= BaseDisplay::ATTRIB_OMNIPRESENT; win->blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_OMNIPRESENT; win->stuck = false; - if (!win->isIconic()) { - BScreen *screen = win->getScreen(); - screen->reassociateWindow(win, screen->getCurrentWorkspace()->workspaceID(), true); - } } else { win->stuck = true; + BScreen *screen = win->getScreen(); + if (!win->isIconic() && !(win->getWorkspaceNumber() != + screen->getCurrentWorkspaceID())) { + screen->reassociateWindow(win, screen->getCurrentWorkspaceID(), true); + } + win->blackbox_attrib.flags |= BaseDisplay::ATTRIB_OMNIPRESENT; win->blackbox_attrib.attrib |= BaseDisplay::ATTRIB_OMNIPRESENT; } @@ -936,9 +940,10 @@ void Tab::insert(Tab *tab) { for (; last->m_next!=0; last=last->m_next); //do sticky before we connect it to the chain //sticky bit on window - if (m_win->isStuck() && !tab->m_win->isStuck() || - !m_win->isStuck() && tab->m_win->isStuck()) - tab->m_win->stick(); //this will set all the m_wins in the list + if (m_win->isStuck() != tab->m_win->isStuck()) { + tab->m_win->stuck = !m_win->stuck; // it will toggle + tab->stick(); //this will set all the m_wins in the list + } //connect the tab to this chain 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 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.cc,v 1.85 2002/09/11 15:12:40 fluxgen Exp $ +// $Id: Window.cc,v 1.86 2002/09/12 14:55:11 rathnor Exp $ #include "Window.hh" @@ -100,7 +100,7 @@ tab(0) { frame.utitle = frame.ftitle = frame.uhandle = frame.fhandle = None; frame.ulabel = frame.flabel = frame.ubutton = frame.fbutton = None; frame.pbutton = frame.ugrip = frame.fgrip = None; - + //get decorations vector dir = fluxbox->getTitlebarLeft(); for (char c=0; c<2; c++) { @@ -164,7 +164,7 @@ tab(0) { fluxbox->ungrab(); return; } - + image_ctrl = screen->getImageControl(); client.x = wattrib.x; @@ -186,7 +186,6 @@ tab(0) { getWMProtocols(); getWMHints(); getWMNormalHints(); - #ifdef SLIT if (client.initial_state == WithdrawnState) { @@ -219,7 +218,7 @@ tab(0) { } upsize(); - + bool place_window = true; if (fluxbox->isStartup() || transient || client.normal_hint_flags & (PPosition|USPosition)) { @@ -319,11 +318,16 @@ tab(0) { int m = maximized; maximized = false; maximize(m); + } + + if (stuck) { + stuck = false; + stick(); + deiconify(); //omnipresent, so show it } setFocusFlag(false); - #ifdef DEBUG fprintf(stderr, "%s(%d): FluxboxWindow(this=%p)\n", __FILE__, __LINE__, this); #endif // DEBUG @@ -1172,7 +1176,7 @@ void FluxboxWindow::getWMProtocols() { Atom *proto; int num_return = 0; Fluxbox *fluxbox = Fluxbox::instance(); - + if (XGetWMProtocols(display, client.window, &proto, &num_return)) { for (int i = 0; i < num_return; ++i) { if (proto[i] == fluxbox->getWMDeleteAtom()) @@ -2062,13 +2066,12 @@ void FluxboxWindow::stick() { stuck = false; - if (! iconic) - screen->reassociateWindow(this, screen->getCurrentWorkspace()->workspaceID(), true); - - } else { stuck = true; - + if (screen->getCurrentWorkspaceID() != workspace_number) { + screen->reassociateWindow(this,screen->getCurrentWorkspaceID(), true); + } + blackbox_attrib.flags |= BaseDisplay::ATTRIB_OMNIPRESENT; blackbox_attrib.attrib |= BaseDisplay::ATTRIB_OMNIPRESENT; 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 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Workspace.cc,v 1.29 2002/09/10 11:03:58 fluxgen Exp $ +// $Id: Workspace.cc,v 1.30 2002/09/12 14:55:11 rathnor Exp $ #include "Workspace.hh" @@ -137,7 +137,8 @@ int Workspace::addWindow(FluxboxWindow *w, bool place) { //update menugraphics m_clientmenu.update(); - screen->updateNetizenWindowAdd(w->getClientWindow(), m_id); + if (!w->isStuck()) + screen->updateNetizenWindowAdd(w->getClientWindow(), m_id); raiseWindow(w); @@ -191,8 +192,9 @@ int Workspace::removeWindow(FluxboxWindow *w) { m_clientmenu.remove(w->getWindowNumber()); m_clientmenu.update(); - - screen->updateNetizenWindowDel(w->getClientWindow()); + + if (!w->isStuck()) + screen->updateNetizenWindowDel(w->getClientWindow()); { Windows::iterator it = windowList.begin(); -- cgit v0.11.2