changed FocusControl::cycleFocus() to take a list of windows as an argument
also fixed some latent bugs and compiler warnings
This commit is contained in:
parent
6de3414135
commit
2f63ba231c
5 changed files with 73 additions and 111 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<Command> CommandRef;
|
||||
typedef SimpleCommand<FluxboxWindow> 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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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!"<<endl;
|
||||
return;
|
||||
}
|
||||
// just make sure we are saving the mods with any other flags (xkb)
|
||||
m_watch_keyrelease = FbTk::KeyUtil::instance().isolateModifierMask(mods);
|
||||
|
||||
if (m_watching_screen == &screen)
|
||||
return;
|
||||
if (m_watching_screen)
|
||||
m_watching_screen->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(),
|
||||
|
|
Loading…
Reference in a new issue