From 2f63ba231cfd6bd8e3191ac0cc516c2235ef0ed2 Mon Sep 17 00:00:00 2001 From: markt Date: Thu, 1 Mar 2007 21:19:04 +0000 Subject: changed FocusControl::cycleFocus() to take a list of windows as an argument also fixed some latent bugs and compiler warnings --- src/FocusControl.cc | 69 ++++++++++++++++++++++++++--------------------------- src/FocusControl.hh | 16 ++++++------- src/Window.cc | 30 +++-------------------- src/WorkspaceCmd.cc | 34 ++++++++++++++++---------- src/fluxbox.cc | 35 ++++++--------------------- 5 files changed, 73 insertions(+), 111 deletions(-) diff --git a/src/FocusControl.cc b/src/FocusControl.cc index 5cbf645..f4c8cdf 100644 --- a/src/FocusControl.cc +++ b/src/FocusControl.cc @@ -54,7 +54,7 @@ FocusControl::FocusControl(BScreen &screen): m_focus_new(screen.resourceManager(), true, screen.name()+".focusNewWindows", screen.altName()+".FocusNewWindows"), - m_cycling_focus(false), + m_cycling_list(0), m_was_iconic(false), m_cycling_last(0) { @@ -79,26 +79,25 @@ bool doSkipWindow(const WinClient &winclient, int opts) { ); } -void FocusControl::cycleFocus(int opts, bool cycle_reverse) { +void FocusControl::cycleFocus(FocusedWindows *window_list, int opts, bool cycle_reverse) { - FocusedWindows *window_list = (opts & CYCLELINEAR) ? &m_creation_order_list : &m_focused_list; - if (!m_cycling_focus) { + if (!m_cycling_list) { if (&m_screen == Fluxbox::instance()->watchingScreen()) - m_cycling_focus = true; - m_cycling_window = find(window_list->begin(),window_list->end(),s_focused_window); - m_cycling_creation_order = (opts & CYCLELINEAR); - m_was_iconic = false; + // only set this when we're waiting for modifiers + m_cycling_list = window_list; + m_was_iconic = 0; m_cycling_last = 0; - } else if (m_cycling_creation_order ^ (bool)(opts & CYCLELINEAR)) { - m_cycling_creation_order ^= true; - m_cycling_window = find(window_list->begin(),window_list->end(),*m_cycling_window); - } - // if it is stacked, we want the highest window in the focused list - // that is on the same workspace + } else if (m_cycling_list != window_list) + m_cycling_list = window_list; + + // too many things can go wrong with remembering this + m_cycling_window = find(window_list->begin(),window_list->end(),s_focused_window); + FocusedWindows::iterator it = m_cycling_window; FocusedWindows::iterator it_begin = window_list->begin(); FocusedWindows::iterator it_end = window_list->end(); + // find the next window in the list that works while (true) { if (cycle_reverse && it == it_begin) it = it_end; @@ -130,12 +129,18 @@ void FocusControl::cycleFocus(int opts, bool cycle_reverse) { // set back to orig current Client in that fbwin m_cycling_last->fbwindow()->setCurrentClient(*m_cycling_last, false); + if (m_was_iconic == m_cycling_last) { + s_reverting = true; // little hack + m_cycling_last->fbwindow()->iconify(); + s_reverting = false; + } } m_cycling_last = &last_client; - if (m_was_iconic) - (*m_cycling_window)->fbwindow()->iconify(); - m_was_iconic = fbwin->isIconic(); - fbwin->tempRaise(); + if (fbwin->isIconic()) + m_was_iconic = m_cycling_last; + if (m_cycling_list) + // else window will raise itself (if desired) on FocusIn + fbwin->tempRaise(); } break; } @@ -158,7 +163,7 @@ void FocusControl::addFocusFront(WinClient &client) { void FocusControl::setFocusBack(FluxboxWindow *fbwin) { // do nothing if there are no windows open // don't change focus order while cycling - if (m_focused_list.empty() || isCycling()) + if (m_focused_list.empty() || s_reverting) return; FocusedWindows::iterator it = m_focused_list.begin(); @@ -181,28 +186,24 @@ void FocusControl::setFocusBack(FluxboxWindow *fbwin) { void FocusControl::stopCyclingFocus() { // nothing to do - if (!m_cycling_focus) + if (m_cycling_list == 0) return; - m_cycling_focus = false; + FocusedWindows::iterator it_end = m_cycling_list->end(); m_cycling_last = 0; + m_cycling_list = 0; + // put currently focused window to top // the iterator may be invalid if the window died // in which case we'll do a proper revert focus - if (m_cycling_creation_order && m_cycling_window != m_creation_order_list.end()) - m_cycling_window = find(m_focused_list.begin(),m_focused_list.end(),*m_cycling_window); - if (m_cycling_window != m_focused_list.end() && - m_cycling_window != m_creation_order_list.end() && - (*m_cycling_window)->fbwindow() && + if (m_cycling_window != it_end && (*m_cycling_window)->fbwindow() && (*m_cycling_window)->fbwindow()->isVisible()) { WinClient *client = *m_cycling_window; - m_focused_list.erase(m_cycling_window); + m_focused_list.remove(client); m_focused_list.push_front(client); client->fbwindow()->raise(); - } else { + } else revertFocus(m_screen); - } - } /** @@ -254,7 +255,6 @@ void FocusControl::setScreenFocusedWindow(WinClient &win_client) { !Fluxbox::instance()->isStartup()) { m_focused_list.remove(&win_client); m_focused_list.push_front(&win_client); - m_cycling_window = m_focused_list.begin(); } } @@ -370,14 +370,14 @@ void FocusControl::removeClient(WinClient &client) { return; WinClient *cyc = 0; - if (m_cycling_window != m_focused_list.end() && m_cycling_window != m_creation_order_list.end()) + if (m_cycling_list && m_cycling_window != m_cycling_list->end()) cyc = *m_cycling_window; m_focused_list.remove(&client); m_creation_order_list.remove(&client); if (cyc == &client) { - m_cycling_window = m_creation_order_list.end(); + m_cycling_window = m_cycling_list->end(); stopCyclingFocus(); } } @@ -402,8 +402,7 @@ void FocusControl::shutdown() { * it gets a focusIn */ void FocusControl::revertFocus(BScreen &screen) { - - if (screen.focusControl().isCycling()) + if (s_reverting) return; FocusControl::s_reverting = true; diff --git a/src/FocusControl.hh b/src/FocusControl.hh index ee5fe95..ee66b9e 100644 --- a/src/FocusControl.hh +++ b/src/FocusControl.hh @@ -68,11 +68,9 @@ public: explicit FocusControl(BScreen &screen); - void prevFocus() { cycleFocus(0, true); } - void nextFocus() { cycleFocus(0, false); } - void prevFocus(int options) { cycleFocus(options, true); } - void nextFocus(int options) { cycleFocus(options, false); } - void cycleFocus(int options, bool cycle_reverse); + void prevFocus() { cycleFocus(&m_focused_list, 0, true); } + void nextFocus() { cycleFocus(&m_focused_list, 0, false); } + void cycleFocus(FocusedWindows *winlist, int options, bool reverse = false); void setScreenFocusedWindow(WinClient &win_client); void setFocusModel(FocusModel model); @@ -83,7 +81,7 @@ public: void dirFocus(FluxboxWindow &win, FocusDir dir); bool isMouseFocus() const { return focusModel() == MOUSEFOCUS; } bool isMouseTabFocus() const { return tabFocusModel() == MOUSETABFOCUS; } - bool isCycling() const { return m_cycling_focus; } + bool isCycling() const { return m_cycling_list != 0; } void addFocusBack(WinClient &client); void addFocusFront(WinClient &client); void setFocusBack(FluxboxWindow *fbwin); @@ -120,10 +118,10 @@ private: // Screen global so it works for sticky windows too. FocusedWindows m_focused_list; FocusedWindows m_creation_order_list; + FocusedWindows::iterator m_cycling_window; - bool m_cycling_focus; - bool m_cycling_creation_order; - bool m_was_iconic; + FocusedWindows *m_cycling_list; + WinClient *m_was_iconic; WinClient *m_cycling_last; static WinClient *s_focused_window; diff --git a/src/Window.cc b/src/Window.cc index 27992f0..4e02bfe 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -777,36 +777,14 @@ void FluxboxWindow::nextClient() { if (numClients() <= 1) return; - ClientList::iterator it = find(m_clientlist.begin(), m_clientlist.end(), m_client); - WinClient *client = 0; - if (it == m_clientlist.end()) { - client = m_clientlist.front(); - } else { - it++; - if (it == m_clientlist.end()) - client = m_clientlist.front(); - else - client = *it; - } - setCurrentClient(*client, true); + screen().focusControl().cycleFocus(&m_clientlist, 0); } void FluxboxWindow::prevClient() { if (numClients() <= 1) return; - ClientList::iterator it = find(m_clientlist.begin(), m_clientlist.end(), m_client); - WinClient *client = 0; - if (it == m_clientlist.end()) { - client = m_clientlist.front(); - } else { - if (it == m_clientlist.begin()) - client = m_clientlist.back(); - else - client = *(--it); - } - - setCurrentClient(*client, true); + screen().focusControl().cycleFocus(&m_clientlist, 0, true); } @@ -3909,8 +3887,6 @@ void FluxboxWindow::setupWindow() { // sets up our window // we allow both to be done at once to share the commands - WinButtonTheme &winbutton_theme = screen().winButtonTheme(); - using namespace FbTk; typedef RefCount CommandRef; typedef SimpleCommand WindowCmd; @@ -4024,7 +4000,7 @@ void FluxboxWindow::updateButtons() { if (new_size != m_titlebar_buttons[i].size() || need_update) need_update = true; else { - for (int j=0; j < new_size && !need_update; j++) { + for (size_t j=0; j < new_size && !need_update; j++) { if ((*(*titlebar_side[i]))[j] != m_titlebar_buttons[i][j]) need_update = true; } diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc index 414f942..7d384aa 100644 --- a/src/WorkspaceCmd.cc +++ b/src/WorkspaceCmd.cc @@ -53,14 +53,19 @@ void NextWindowCmd::execute() { } else if (ev.type == ButtonPress) { mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); } + int options = m_option; if (mods == 0) // can't stacked cycle unless there is a mod to grab - screen->focusControl().nextFocus(m_option | FocusControl::CYCLELINEAR); - else { - // if stacked cycling, then set a watch for - // the release of exactly these modifiers + options |= FocusControl::CYCLELINEAR; + else + // set a watch for the release of exactly these modifiers fb->watchKeyRelease(*screen, mods); - screen->focusControl().nextFocus(m_option); - } + + FocusControl::FocusedWindows *win_list = + (options & FocusControl::CYCLELINEAR) ? + &screen->focusControl().creationOrderList() : + &screen->focusControl().focusedOrderList(); + + screen->focusControl().cycleFocus(win_list, m_option); } } @@ -76,14 +81,19 @@ void PrevWindowCmd::execute() { } else if (ev.type == ButtonPress) { mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); } + int options = m_option; if (mods == 0) // can't stacked cycle unless there is a mod to grab - screen->focusControl().prevFocus(m_option | FocusControl::CYCLELINEAR); - else { - // if stacked cycling, then set a watch for - // the release of exactly these modifiers + options |= FocusControl::CYCLELINEAR; + else + // set a watch for the release of exactly these modifiers fb->watchKeyRelease(*screen, mods); - screen->focusControl().prevFocus(m_option); - } + + FocusControl::FocusedWindows *win_list = + (options & FocusControl::CYCLELINEAR) ? + &screen->focusControl().creationOrderList() : + &screen->focusControl().focusedOrderList(); + + screen->focusControl().cycleFocus(win_list, m_option, true); } } diff --git a/src/fluxbox.cc b/src/fluxbox.cc index 468e723..89bd0d5 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -970,19 +970,7 @@ void Fluxbox::handleButtonEvent(XButtonEvent &be) { if (be.button == 1 && !screen->isRootColormapInstalled()) screen->imageControl().installRootColormap(); - // see if we need to keep watching for key releases - BScreen *old_watching_screen = m_watching_screen; - m_watching_screen = 0; - if (!m_key->doAction(be.type, be.state, be.button)) - // no command run, so could still be cycling - m_watching_screen = old_watching_screen; - else if (old_watching_screen && - m_watching_screen != old_watching_screen) { - // no longer need to watch old screen, so stop cycling - old_watching_screen->notifyReleasedKeys(); - if (!m_watching_screen) - XUngrabKeyboard(FbTk::App::instance()->display(), CurrentTime); - } + m_key->doAction(be.type, be.state, be.button); } void Fluxbox::handleUnmapNotify(XUnmapEvent &ue) { @@ -1113,21 +1101,9 @@ void Fluxbox::handleKeyEvent(XKeyEvent &ke) { if (keyScreen() == 0 || mouseScreen() == 0) return; - BScreen *old_watching_screen = m_watching_screen; - switch (ke.type) { case KeyPress: - // see if we need to keep watching for key releases - m_watching_screen = 0; - if (!m_key->doAction(ke.type, ke.state, ke.keycode)) - // no command run, so could still be cycling - m_watching_screen = old_watching_screen; - else if (old_watching_screen && - m_watching_screen != old_watching_screen) { - old_watching_screen->notifyReleasedKeys(); - if (!m_watching_screen) - XUngrabKeyboard(FbTk::App::instance()->display(), CurrentTime); - } + m_key->doAction(ke.type, ke.state, ke.keycode); break; case KeyRelease: { // we ignore most key releases unless we need to use @@ -1841,12 +1817,15 @@ void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) { cerr<<"WARNING: attempt to grab without modifiers!"<focusControl().stopCyclingFocus(); m_watching_screen = &screen; - // just make sure we are saving the mods with any other flags (xkb) - m_watch_keyrelease = FbTk::KeyUtil::instance().isolateModifierMask(mods); // TODO: it's possible (and happens to me sometimes) for the mods to be // released before we grab the keyboard -- not sure of a good way to fix it XGrabKeyboard(FbTk::App::instance()->display(), -- cgit v0.11.2