all repos — fluxbox @ 5ceacc65925f597180c918fcaa2a8171c42cbcdd

custom fork of the fluxbox windowmanager

moved all focus handling to FocusControl
fluxgen fluxgen
commit

5ceacc65925f597180c918fcaa2a8171c42cbcdd

parent

f53c93e5e0add69771204056550d07b4fee4efef

M src/CommandDialog.ccsrc/CommandDialog.cc

@@ -28,7 +28,7 @@ #include "Screen.hh"

#include "FbWinFrameTheme.hh" #include "WinClient.hh" #include "CommandParser.hh" -#include "fluxbox.hh" +#include "FocusControl.hh" #include "FbTk/ImageControl.hh" #include "FbTk/EventManager.hh"

@@ -90,9 +90,9 @@ void CommandDialog::hide() {

FbTk::FbWindow::hide(); // return focus to fluxbox window - if (Fluxbox::instance()->getFocusedWindow() && - Fluxbox::instance()->getFocusedWindow()->fbwindow()) - Fluxbox::instance()->getFocusedWindow()->fbwindow()->setInputFocus(); + if (FocusControl::focusedWindow() && + FocusControl::focusedWindow()->fbwindow()) + FocusControl::focusedWindow()->fbwindow()->setInputFocus(); }
M src/CurrentWindowCmd.ccsrc/CurrentWindowCmd.cc

@@ -29,10 +29,12 @@ #include "Window.hh"

#include "Screen.hh" #include "WinClient.hh" +#include "FocusControl.hh" + CurrentWindowCmd::CurrentWindowCmd(Action act):m_action(act) { } void CurrentWindowCmd::execute() { - WinClient *client = Fluxbox::instance()->getFocusedWindow(); + WinClient *client = FocusControl::focusedWindow(); if (client && client->fbwindow()) (client->fbwindow()->*m_action)(); }

@@ -95,19 +97,19 @@ fbwindow().setCurrentClient(**it, true);

} void WindowHelperCmd::execute() { - WinClient *client = Fluxbox::instance()->getFocusedWindow(); + WinClient *client = FocusControl::focusedWindow(); if (client && client->fbwindow()) // guarantee that fbwindow() exists too real_execute(); } WinClient &WindowHelperCmd::winclient() { // will exist from execute above - return *Fluxbox::instance()->getFocusedWindow(); + return *FocusControl::focusedWindow(); } FluxboxWindow &WindowHelperCmd::fbwindow() { // will exist from execute above - return *Fluxbox::instance()->getFocusedWindow()->fbwindow(); + return *FocusControl::focusedWindow()->fbwindow(); } MoveCmd::MoveCmd(const int step_size_x, const int step_size_y) :
M src/FocusControl.ccsrc/FocusControl.cc

@@ -142,7 +142,7 @@

FluxboxWindow *focused_group = 0; // start from the focused window bool have_focused = false; - WinClient *focused = Fluxbox::instance()->getFocusedWindow(); + WinClient *focused = focusedWindow(); if (focused != 0) { if (focused->screen().screenNumber() == m_screen.screenNumber()) { have_focused = true;

@@ -197,7 +197,7 @@ m_focused_list.erase(m_cycling_window);

m_focused_list.push_front(client); client->fbwindow()->raise(); } else { - Fluxbox::instance()->revertFocus(m_screen); + revertFocus(m_screen); } }

@@ -307,7 +307,7 @@

FluxboxWindow *focused_group = 0; // start from the focused window bool have_focused = false; - WinClient *focused = Fluxbox::instance()->getFocusedWindow(); + WinClient *focused = focusedWindow(); if (focused != 0) { if (focused->screen().screenNumber() == m_screen.screenNumber()) { have_focused = true;

@@ -340,11 +340,11 @@ }

void FocusControl::raiseFocus() { bool have_focused = false; - Fluxbox &fb = *Fluxbox::instance(); + // set have_focused if the currently focused window // is on this screen - if (fb.getFocusedWindow()) { - if (fb.getFocusedWindow()->screen().screenNumber() == m_screen.screenNumber()) { + if (focusedWindow()) { + if (focusedWindow()->screen().screenNumber() == m_screen.screenNumber()) { have_focused = true; } }

@@ -352,7 +352,7 @@

// if we have a focused window on this screen and // number of windows is greater than one raise the focused window if (m_screen.currentWorkspace()->numberOfWindows() > 1 && have_focused) - fb.getFocusedWindow()->raise(); + focusedWindow()->raise(); }

@@ -402,9 +402,12 @@ // we check things against an edge, and within the bounds (draw a picture)

int edge=0, upper=0, lower=0, oedge=0, oupper=0, olower=0; int otop = (*it)->y(), + // 2 * border = border on each side obottom = (*it)->y() + (*it)->height() + 2*borderW, oleft = (*it)->x(), + // 2 * border = border on each side oright = (*it)->x() + (*it)->width() + 2*borderW; + // check if they intersect switch (dir) { case FOCUSUP:

@@ -441,7 +444,9 @@ olower = obottom;

break; } - if (oedge < edge) continue; // not in the right direction + if (oedge < edge) + continue; // not in the right direction + if (olower <= upper || oupper >= lower) { // outside our horz bounds, get a heavy weight penalty int myweight = 100000 + oedge - edge + abs(upper-oupper)+abs(lower-olower);

@@ -475,6 +480,7 @@ if (m_cycling_window != m_focused_list.end())

cyc = *m_cycling_window; m_focused_list.remove(&client); + if (cyc == &client) { m_cycling_window = m_focused_list.end(); }

@@ -548,9 +554,8 @@ while (trans_parent) {

if (trans_parent->fbwindow() && // can't focus if no fbwin (!unfocus_frame || trans_parent->fbwindow() != fbwin) && // can't be this window trans_parent->fbwindow()->isVisible() && - trans_parent->fbwindow()-> - setCurrentClient(*trans_parent, - Fluxbox::instance()->getFocusedWindow() == &client)) { + trans_parent->fbwindow()->setCurrentClient(*trans_parent, + s_focused_window == &client)) { return; } trans_parent = trans_parent->transientFor();

@@ -565,19 +570,23 @@ if (!unfocus_frame) {

WinClient *last_focus = screen.focusControl().lastFocusedWindow(*fbwin, &client); if (last_focus != 0 && fbwin->setCurrentClient(*last_focus, - Fluxbox::instance()->getFocusedWindow() == &client)) { + s_focused_window == &client)) { return; } } - if (full_revert && Fluxbox::instance()->getFocusedWindow() == &client) + if (full_revert && s_focused_window == &client) revertFocus(screen); } void FocusControl::setFocusedWindow(WinClient *client) { - assert(false); + BScreen *screen = client ? &client->screen() : 0; + BScreen *old_screen = + FocusControl::focusedWindow() ? + &FocusControl::focusedWindow()->screen() : 0; + #ifdef DEBUG cerr<<__FILE__<<endl; cerr<<"------------------"<<endl;

@@ -587,38 +596,40 @@ cerr<<"title: "<<client->fbwindow()->title()<<endl;

cerr<<"Current Focused window = "<<s_focused_window<<endl; cerr<<"------------------"<<endl; #endif // DEBUG - /* + WinClient *old_client = 0; // Update the old focused client to non focus - if (s_focused_window != 0) { - // check if s_focused_window is valid + // check if s_focused_window is valid + if (s_focused_window != 0 && + Fluxbox::instance()->validateClient(s_focused_window)) { - if (Fluxbox::instance()->searchWindow(s_focused_window) != 0) { - s_focused_window = 0; - } else { - old_client = s_focused_window; - if (old_client->fbwindow()) { - FluxboxWindow *old_win = old_client->fbwindow(); + old_client = s_focused_window; + if (old_client->fbwindow()) { + FluxboxWindow *old_win = old_client->fbwindow(); + + if (!client || client->fbwindow() != old_win) + old_win->setFocusFlag(false); + } - if (!client || client->fbwindow() != old_win) - old_win->setFocusFlag(false); - } - } + } else { + s_focused_window = 0; } + if (client && client->fbwindow() && !client->fbwindow()->isIconic()) { // screen should be ok FluxboxWindow *win = client->fbwindow(); s_focused_window = client; // update focused window - win->setCurrentClient(*client, false); // don't setinputfocus + win->setCurrentClient(*client, + false); // don't set inputfocus win->setFocusFlag(true); // set focus flag } else s_focused_window = 0; - Fluxbox::instance()->updateFocusedWindow(s_focused_window, old_client); - */ + // update AtomHandlers and/or other stuff... + Fluxbox::instance()->updateFocusedWindow(screen, old_screen); } ////////////////////// FocusControl RESOURCES
M src/FocusControl.hhsrc/FocusControl.hh

@@ -96,7 +96,8 @@

void removeClient(WinClient &client); static void revertFocus(BScreen &screen); - static void unfocusWindow(WinClient &client, bool full_revert, bool unfocus_frame); + // like revertFocus, but specifically related to this window (transients etc) + static void unfocusWindow(WinClient &client, bool full_revert = true, bool unfocus_frame = false); static void setFocusedWindow(WinClient *focus_to); static WinClient *focusedWindow() { return s_focused_window; } private:
M src/IconbarTool.ccsrc/IconbarTool.cc

@@ -34,6 +34,7 @@ #include "FbMenu.hh"

#include "BoolMenuItem.hh" #include "CommandParser.hh" #include "WinClient.hh" +#include "FocusControl.hh" #include "FbTk/I18n.hh" #include "FbTk/Menu.hh"

@@ -948,7 +949,7 @@ renderTheme();

} void IconbarTool::timedRender() { - WinClient *client = Fluxbox::instance()->getFocusedWindow(); + WinClient *client = FocusControl::focusedWindow(); if (client == 0 || client->fbwindow() == 0) return;
M src/Screen.ccsrc/Screen.cc

@@ -925,7 +925,7 @@ return;

FbTk::App::instance()->sync(false); - WinClient *focused_client = Fluxbox::instance()->getFocusedWindow(); + WinClient *focused_client = FocusControl::focusedWindow(); FluxboxWindow *focused = 0; if (focused_client) focused = focused_client->fbwindow();

@@ -966,7 +966,7 @@

if (focused && (focused->isStuck() || focused->isMoving())) focused->setInputFocus(); else - Fluxbox::instance()->revertFocus(*this); + FocusControl::revertFocus(*this); if (focused && focused->isMoving()) focused->resumeMoving();

@@ -982,7 +982,7 @@ if (! m_current_workspace || id >= m_workspaces_list.size())

return; if (!win) { - WinClient *client = Fluxbox::instance()->getFocusedWindow(); + WinClient *client = FocusControl::focusedWindow(); if (client) win = client->fbwindow(); }

@@ -1039,8 +1039,8 @@ (*it)->workspaceID());

} } - Window f = ((Fluxbox::instance()->getFocusedWindow()) ? - Fluxbox::instance()->getFocusedWindow()->window() : None); + Window f = ((FocusControl::focusedWindow()) ? + FocusControl::focusedWindow()->window() : None); net->sendWindowFocus(f); }

@@ -1075,8 +1075,8 @@ }

void BScreen::updateNetizenWindowFocus() { - Window f = ((Fluxbox::instance()->getFocusedWindow()) ? - Fluxbox::instance()->getFocusedWindow()->window() : None); + Window f = ((FocusControl::focusedWindow()) ? + FocusControl::focusedWindow()->window() : None); for_each(m_netizen_list.begin(), m_netizen_list.end(), bind2nd(mem_fun(&Netizen::sendWindowFocus), f));
M src/Window.ccsrc/Window.cc

@@ -622,7 +622,7 @@

// reparent client win to this frame frame().setClientWindow(client); WinClient *was_focused = 0; - WinClient *focused_win = Fluxbox::instance()->getFocusedWindow(); + WinClient *focused_win = FocusControl::focusedWindow(); // get the current window on the end of our client list Window leftwin = None;
M src/Workspace.ccsrc/Workspace.cc

@@ -32,6 +32,7 @@ #include "Window.hh"

#include "WinClient.hh" #include "FbWinFrame.hh" #include "WindowCmd.hh" +#include "FocusControl.hh" #include "FbTk/I18n.hh" #include "FbTk/MenuItem.hh"

@@ -207,7 +208,7 @@ m_lastfocus = 0;

} if (w->isFocused() && still_alive) - Fluxbox::instance()->unfocusWindow(w->winClient(), true, true); + FocusControl::unfocusWindow(w->winClient(), true, true); // we don't remove it from the layermanager, as it may be being moved Windows::iterator erase_it = remove(m_windowlist.begin(),
M src/WorkspaceCmd.ccsrc/WorkspaceCmd.cc

@@ -29,6 +29,7 @@ #include "Window.hh"

#include "Screen.hh" #include "fluxbox.hh" #include "WinClient.hh" +#include "FocusControl.hh" #include "FbTk/KeyUtil.hh"

@@ -92,7 +93,7 @@ BScreen *screen = Fluxbox::instance()->keyScreen();

if (screen == 0) return; - WinClient *client = Fluxbox::instance()->getFocusedWindow(); + WinClient *client = FocusControl::focusedWindow(); if (client == 0 || client->fbwindow() == 0) return;
M src/fluxbox.ccsrc/fluxbox.cc

@@ -224,7 +224,7 @@ m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"),

m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"), m_rc_auto_raise_delay(m_resourcemanager, 250, "session.autoRaiseDelay", "Session.AutoRaiseDelay"), m_rc_use_mod1(m_resourcemanager, true, "session.useMod1", "Session.UseMod1"), - m_focused_window(0), m_masked_window(0), + m_masked_window(0), m_mousescreen(0), m_keyscreen(0), m_watching_screen(0), m_watch_keyrelease(0),

@@ -511,7 +511,7 @@ it++) {

(*it).first->initForScreen(*screen); } - revertFocus(*screen); // make sure focus style is correct + FocusControl::revertFocus(*screen); // make sure focus style is correct #ifdef SLIT if (screen->slit()) screen->slit()->show();

@@ -694,7 +694,7 @@ }

} if (screen != 0) - revertFocus(*screen); + FocusControl::revertFocus(*screen); } // try FbTk::EventHandler first

@@ -870,8 +870,8 @@ e->xfocus.detail == NotifyPointer ||

e->xfocus.detail == NotifyInferior) break; WinClient *winclient = searchWindow(e->xfocus.window); - if (winclient && m_focused_window != winclient) - setFocusedWindow(winclient); + if (winclient && FocusControl::focusedWindow() != winclient) + FocusControl::setFocusedWindow(winclient); } break; case FocusOut:{

@@ -886,11 +886,11 @@ if (winclient == 0 && FbTk::Menu::focused() == 0) {

#ifdef DEBUG cerr<<__FILE__<<"("<<__FUNCTION__<<") Focus out is not a FluxboxWindow !!"<<endl; #endif // DEBUG - } else if (winclient && winclient == m_focused_window && + } else if (winclient && winclient == FocusControl::focusedWindow() && (winclient->fbwindow() == 0 || !winclient->fbwindow()->isMoving())) // we don't unfocus a moving window - setFocusedWindow(0); + FocusControl::setFocusedWindow(0); } break; case ClientMessage:

@@ -1224,8 +1224,8 @@

// make sure each workspace get this BScreen &scr = win.screen(); scr.removeWindow(&win); - if (m_focused_window == &win.winClient()) - m_focused_window = 0; + if (FocusControl::focusedWindow() == &win.winClient()) + FocusControl::setFocusedWindow(0); } else if ((&(win.workspaceSig())) == changedsub) { // workspace signal for (AtomHandlerContainerIt it= m_atomhandler.begin();

@@ -1297,12 +1297,12 @@ // We also assume that any remaining active one is the last focused one

// This is where we revert focus on window close // NOWHERE ELSE!!! - if (m_focused_window == &client) - unfocusWindow(client); + if (FocusControl::focusedWindow() == &client) + FocusControl::unfocusWindow(client); // failed to revert focus? - if (m_focused_window == &client) - m_focused_window = 0; + if (FocusControl::focusedWindow() == &client) + FocusControl::setFocusedWindow(0); } }

@@ -1796,73 +1796,22 @@

m_reconfigure_wait = m_reread_menu_wait = false; } -// set focused window -void Fluxbox::setFocusedWindow(WinClient *client) { - // already focused - if (m_focused_window == client) { -#ifdef DEBUG - cerr<<"Focused window already win"<<endl; -#endif // DEBUG - return; - } -#ifdef DEBUG - cerr<<"Setting Focused window = "<<client<<endl; - if (client != 0 && client->fbwindow() != 0) - cerr<<"title: "<<client->fbwindow()->title()<<endl; - cerr<<"Current Focused window = "<<m_focused_window<<endl; - cerr<<"------------------"<<endl; -#endif // DEBUG - BScreen *old_screen = 0, *screen = 0; - WinClient *old_client = 0; +bool Fluxbox::validateClient(const WinClient *client) const { + WinClientMap::const_iterator it = + find_if(m_window_search.begin(), + m_window_search.end(), + Compose(bind2nd(equal_to<WinClient *>(), client), + Select2nd<WinClientMap::value_type>())); + return it != m_window_search.end(); +} - if (m_focused_window != 0) { - // check if m_focused_window is valid - WinClientMap::iterator it = find_if(m_window_search.begin(), - m_window_search.end(), - Compose(bind2nd(equal_to<WinClient *>(), m_focused_window), - Select2nd<WinClientMap::value_type>())); - - // if not found... - if (it == m_window_search.end()) { - m_focused_window = 0; - } else { - old_client = m_focused_window; - old_screen = &old_client->screen(); - - if (old_client->fbwindow()) { - FluxboxWindow *old_win = old_client->fbwindow(); - - if (!client || client->fbwindow() != old_win) - old_win->setFocusFlag(false); - } - } - } - - if (client && client->fbwindow() && !client->fbwindow()->isIconic()) { - FluxboxWindow *win = client->fbwindow(); - // make sure we have a valid win pointer with a valid screen - ScreenList::iterator winscreen = - std::find(m_screen_list.begin(), m_screen_list.end(), - &client->screen()); - if (winscreen == m_screen_list.end()) { - m_focused_window = 0; // the window pointer wasn't valid, mark no window focused - } else { - screen = *winscreen; - m_focused_window = client; // update focused window - win->setCurrentClient(*client, false); // don't setinputfocus - win->setFocusFlag(true); // set focus flag - } - - } else - m_focused_window = 0; - - +void Fluxbox::updateFocusedWindow(BScreen *screen, BScreen *old_screen) { if (screen != 0) { screen->updateNetizenWindowFocus(); for (AtomHandlerContainerIt it= m_atomhandler.begin(); it != m_atomhandler.end(); it++) { - (*it).first->updateFocusedWindow(*screen, (m_focused_window ? - m_focused_window->window() : + (*it).first->updateFocusedWindow(*screen, (FocusControl::focusedWindow() ? + FocusControl::focusedWindow()->window() : 0)); } }

@@ -1874,88 +1823,6 @@ it != m_atomhandler.end(); it++)

(*it).first->updateFocusedWindow(*old_screen, 0); } } - -/** - * This function is called whenever we aren't quite sure what - * focus is meant to be, it'll make things right ;-) - * last_focused is set to something if we want to make use of the - * previously focused window (it must NOT be set focused now, it - * is probably dying). - * - * ignore_event means that it ignores the given event until - * it gets a focusIn - */ -void Fluxbox::revertFocus(BScreen &screen) { - // Relevant resources: - // resource.focus_last = whether we focus last focused when changing workspace - // BScreen::FocusModel = sloppy, click, whatever - WinClient *next_focus = screen.focusControl().lastFocusedWindow(screen.currentWorkspaceID()); - - // if setting focus fails, or isn't possible, fallback correctly - if (!(next_focus && next_focus->fbwindow() && - next_focus->fbwindow()->setCurrentClient(*next_focus, true))) { - setFocusedWindow(0); // so we don't get dangling m_focused_window pointer - switch (screen.focusControl().focusModel()) { - case FocusControl::MOUSEFOCUS: - XSetInputFocus(FbTk::App::instance()->display(), - PointerRoot, None, CurrentTime); - break; - case FocusControl::CLICKFOCUS: - screen.rootWindow().setInputFocus(RevertToPointerRoot, CurrentTime); - break; - } - } -} - -/* - * Like revertFocus, but specifically related to this window (transients etc) - * if full_revert, we fallback to a full revertFocus if we can't find anything - * local to the client. - * If unfocus_frame is true, we won't focus anything in the same frame - * as the client. - * - * So, we first prefer to choose a transient parent, then the last - * client in this window, and if no luck (or unfocus_frame), then - * we just use the normal revertFocus on the screen. - * - * assumption: client has focus - */ -void Fluxbox::unfocusWindow(WinClient &client, bool full_revert, bool unfocus_frame) { - // go up the transient tree looking for a focusable window - - FluxboxWindow *fbwin = client.fbwindow(); - if (fbwin == 0) - unfocus_frame = false; - - WinClient *trans_parent = client.transientFor(); - while (trans_parent) { - if (trans_parent->fbwindow() && // can't focus if no fbwin - (!unfocus_frame || trans_parent->fbwindow() != fbwin) && // can't be this window - trans_parent->fbwindow()->isVisible() && - trans_parent->fbwindow()->setCurrentClient(*trans_parent, m_focused_window == &client)) { - return; - } - trans_parent = trans_parent->transientFor(); - } - - if (fbwin == 0) - return; // nothing more we can do - - BScreen &screen = fbwin->screen(); - - if (!unfocus_frame) { - WinClient *last_focus = screen.focusControl().lastFocusedWindow(*fbwin, &client); - if (last_focus != 0 && - fbwin->setCurrentClient(*last_focus, m_focused_window == &client)) { - return; - } - } - - if (full_revert && m_focused_window == &client) - revertFocus(screen); - -} - void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) {
M src/fluxbox.hhsrc/fluxbox.hh

@@ -89,6 +89,8 @@

/// main event loop void eventLoop(); bool validateWindow(Window win) const; + bool validateClient(const WinClient *client) const; + void grab(); void ungrab(); Keys *keys() { return m_key.get(); }

@@ -97,7 +99,6 @@

// Not currently implemented until we decide how it'll be used //WinClient *searchGroup(Window); WinClient *searchWindow(Window); - WinClient *getFocusedWindow() { return m_focused_window; } int initScreen(int screen_nr); BScreen *searchScreen(Window w);

@@ -134,6 +135,7 @@

// class to store layer numbers (special Resource type) // we have a special resource type because we need to be able to name certain layers // a Resource<int> wouldn't allow this + class Layer { public: explicit Layer(int i) : m_num(i) {};

@@ -166,10 +168,6 @@ { m_masked = w; m_masked_window = bw; }

void watchKeyRelease(BScreen &screen, unsigned int mods); - void setFocusedWindow(WinClient *w); - void revertFocus(BScreen &screen); - // like revertFocus, but specifically related to this window (transients etc) - void unfocusWindow(WinClient &client, bool full_revert = true, bool unfocus_frame = false); void shutdown(); void load_rc(BScreen &scr); void loadRootCommand(BScreen &scr);

@@ -200,6 +198,12 @@

/// handle any system signal sent to the application void handleSignal(int signum); void update(FbTk::Subject *changed); + /** + * Sends update signal to atomhandlers, + * @param screen the new screen + * @param old_screen the old screen if any, can be the same as new screen + */ + void updateFocusedWindow(BScreen *screen, BScreen *old_screen); void attachSignals(FluxboxWindow &win); void attachSignals(WinClient &winclient);

@@ -227,7 +231,7 @@ BScreen *keyScreen() { return m_keyscreen; }

// screen we are watching for modifier changes BScreen *watchingScreen() { return m_watching_screen; } const XEvent &lastEvent() const { return m_last_event; } - + private: typedef struct MenuTimestamp {

@@ -292,7 +296,6 @@ std::list<MenuTimestamp *> m_menu_timestamps;

typedef std::list<BScreen *> ScreenList; ScreenList m_screen_list; - WinClient *m_focused_window; FluxboxWindow *m_masked_window; BScreen *m_mousescreen, *m_keyscreen;