moved all focus handling to FocusControl

This commit is contained in:
fluxgen 2006-02-18 20:19:22 +00:00
parent f53c93e5e0
commit 5ceacc6592
11 changed files with 101 additions and 214 deletions

View file

@ -28,7 +28,7 @@
#include "FbWinFrameTheme.hh" #include "FbWinFrameTheme.hh"
#include "WinClient.hh" #include "WinClient.hh"
#include "CommandParser.hh" #include "CommandParser.hh"
#include "fluxbox.hh" #include "FocusControl.hh"
#include "FbTk/ImageControl.hh" #include "FbTk/ImageControl.hh"
#include "FbTk/EventManager.hh" #include "FbTk/EventManager.hh"
@ -90,9 +90,9 @@ void CommandDialog::hide() {
FbTk::FbWindow::hide(); FbTk::FbWindow::hide();
// return focus to fluxbox window // return focus to fluxbox window
if (Fluxbox::instance()->getFocusedWindow() && if (FocusControl::focusedWindow() &&
Fluxbox::instance()->getFocusedWindow()->fbwindow()) FocusControl::focusedWindow()->fbwindow())
Fluxbox::instance()->getFocusedWindow()->fbwindow()->setInputFocus(); FocusControl::focusedWindow()->fbwindow()->setInputFocus();
} }

View file

@ -29,10 +29,12 @@
#include "Screen.hh" #include "Screen.hh"
#include "WinClient.hh" #include "WinClient.hh"
#include "FocusControl.hh"
CurrentWindowCmd::CurrentWindowCmd(Action act):m_action(act) { } CurrentWindowCmd::CurrentWindowCmd(Action act):m_action(act) { }
void CurrentWindowCmd::execute() { void CurrentWindowCmd::execute() {
WinClient *client = Fluxbox::instance()->getFocusedWindow(); WinClient *client = FocusControl::focusedWindow();
if (client && client->fbwindow()) if (client && client->fbwindow())
(client->fbwindow()->*m_action)(); (client->fbwindow()->*m_action)();
} }
@ -95,19 +97,19 @@ void GoToTabCmd::real_execute() {
} }
void WindowHelperCmd::execute() { void WindowHelperCmd::execute() {
WinClient *client = Fluxbox::instance()->getFocusedWindow(); WinClient *client = FocusControl::focusedWindow();
if (client && client->fbwindow()) // guarantee that fbwindow() exists too if (client && client->fbwindow()) // guarantee that fbwindow() exists too
real_execute(); real_execute();
} }
WinClient &WindowHelperCmd::winclient() { WinClient &WindowHelperCmd::winclient() {
// will exist from execute above // will exist from execute above
return *Fluxbox::instance()->getFocusedWindow(); return *FocusControl::focusedWindow();
} }
FluxboxWindow &WindowHelperCmd::fbwindow() { FluxboxWindow &WindowHelperCmd::fbwindow() {
// will exist from execute above // 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) : MoveCmd::MoveCmd(const int step_size_x, const int step_size_y) :

View file

@ -142,7 +142,7 @@ void FocusControl::prevFocus(int opts) {
FluxboxWindow *focused_group = 0; FluxboxWindow *focused_group = 0;
// start from the focused window // start from the focused window
bool have_focused = false; bool have_focused = false;
WinClient *focused = Fluxbox::instance()->getFocusedWindow(); WinClient *focused = focusedWindow();
if (focused != 0) { if (focused != 0) {
if (focused->screen().screenNumber() == m_screen.screenNumber()) { if (focused->screen().screenNumber() == m_screen.screenNumber()) {
have_focused = true; have_focused = true;
@ -197,7 +197,7 @@ void FocusControl::stopCyclingFocus() {
m_focused_list.push_front(client); m_focused_list.push_front(client);
client->fbwindow()->raise(); client->fbwindow()->raise();
} else { } else {
Fluxbox::instance()->revertFocus(m_screen); revertFocus(m_screen);
} }
} }
@ -307,7 +307,7 @@ void FocusControl::nextFocus(int opts) {
FluxboxWindow *focused_group = 0; FluxboxWindow *focused_group = 0;
// start from the focused window // start from the focused window
bool have_focused = false; bool have_focused = false;
WinClient *focused = Fluxbox::instance()->getFocusedWindow(); WinClient *focused = focusedWindow();
if (focused != 0) { if (focused != 0) {
if (focused->screen().screenNumber() == m_screen.screenNumber()) { if (focused->screen().screenNumber() == m_screen.screenNumber()) {
have_focused = true; have_focused = true;
@ -340,11 +340,11 @@ void FocusControl::nextFocus(int opts) {
void FocusControl::raiseFocus() { void FocusControl::raiseFocus() {
bool have_focused = false; bool have_focused = false;
Fluxbox &fb = *Fluxbox::instance();
// set have_focused if the currently focused window // set have_focused if the currently focused window
// is on this screen // is on this screen
if (fb.getFocusedWindow()) { if (focusedWindow()) {
if (fb.getFocusedWindow()->screen().screenNumber() == m_screen.screenNumber()) { if (focusedWindow()->screen().screenNumber() == m_screen.screenNumber()) {
have_focused = true; have_focused = true;
} }
} }
@ -352,7 +352,7 @@ void FocusControl::raiseFocus() {
// if we have a focused window on this screen and // if we have a focused window on this screen and
// number of windows is greater than one raise the focused window // number of windows is greater than one raise the focused window
if (m_screen.currentWorkspace()->numberOfWindows() > 1 && have_focused) if (m_screen.currentWorkspace()->numberOfWindows() > 1 && have_focused)
fb.getFocusedWindow()->raise(); focusedWindow()->raise();
} }
@ -402,9 +402,12 @@ void FocusControl::dirFocus(FluxboxWindow &win, FocusDir dir) {
int edge=0, upper=0, lower=0, oedge=0, oupper=0, olower=0; int edge=0, upper=0, lower=0, oedge=0, oupper=0, olower=0;
int otop = (*it)->y(), int otop = (*it)->y(),
// 2 * border = border on each side
obottom = (*it)->y() + (*it)->height() + 2*borderW, obottom = (*it)->y() + (*it)->height() + 2*borderW,
oleft = (*it)->x(), oleft = (*it)->x(),
// 2 * border = border on each side
oright = (*it)->x() + (*it)->width() + 2*borderW; oright = (*it)->x() + (*it)->width() + 2*borderW;
// check if they intersect // check if they intersect
switch (dir) { switch (dir) {
case FOCUSUP: case FOCUSUP:
@ -441,7 +444,9 @@ void FocusControl::dirFocus(FluxboxWindow &win, FocusDir dir) {
break; break;
} }
if (oedge < edge) continue; // not in the right direction if (oedge < edge)
continue; // not in the right direction
if (olower <= upper || oupper >= lower) { if (olower <= upper || oupper >= lower) {
// outside our horz bounds, get a heavy weight penalty // outside our horz bounds, get a heavy weight penalty
int myweight = 100000 + oedge - edge + abs(upper-oupper)+abs(lower-olower); int myweight = 100000 + oedge - edge + abs(upper-oupper)+abs(lower-olower);
@ -475,6 +480,7 @@ void FocusControl::removeClient(WinClient &client) {
cyc = *m_cycling_window; cyc = *m_cycling_window;
m_focused_list.remove(&client); m_focused_list.remove(&client);
if (cyc == &client) { if (cyc == &client) {
m_cycling_window = m_focused_list.end(); m_cycling_window = m_focused_list.end();
} }
@ -548,9 +554,8 @@ void FocusControl::unfocusWindow(WinClient &client,
if (trans_parent->fbwindow() && // can't focus if no fbwin if (trans_parent->fbwindow() && // can't focus if no fbwin
(!unfocus_frame || trans_parent->fbwindow() != fbwin) && // can't be this window (!unfocus_frame || trans_parent->fbwindow() != fbwin) && // can't be this window
trans_parent->fbwindow()->isVisible() && trans_parent->fbwindow()->isVisible() &&
trans_parent->fbwindow()-> trans_parent->fbwindow()->setCurrentClient(*trans_parent,
setCurrentClient(*trans_parent, s_focused_window == &client)) {
Fluxbox::instance()->getFocusedWindow() == &client)) {
return; return;
} }
trans_parent = trans_parent->transientFor(); trans_parent = trans_parent->transientFor();
@ -565,19 +570,23 @@ void FocusControl::unfocusWindow(WinClient &client,
WinClient *last_focus = screen.focusControl().lastFocusedWindow(*fbwin, &client); WinClient *last_focus = screen.focusControl().lastFocusedWindow(*fbwin, &client);
if (last_focus != 0 && if (last_focus != 0 &&
fbwin->setCurrentClient(*last_focus, fbwin->setCurrentClient(*last_focus,
Fluxbox::instance()->getFocusedWindow() == &client)) { s_focused_window == &client)) {
return; return;
} }
} }
if (full_revert && Fluxbox::instance()->getFocusedWindow() == &client) if (full_revert && s_focused_window == &client)
revertFocus(screen); revertFocus(screen);
} }
void FocusControl::setFocusedWindow(WinClient *client) { void FocusControl::setFocusedWindow(WinClient *client) {
assert(false); BScreen *screen = client ? &client->screen() : 0;
BScreen *old_screen =
FocusControl::focusedWindow() ?
&FocusControl::focusedWindow()->screen() : 0;
#ifdef DEBUG #ifdef DEBUG
cerr<<__FILE__<<endl; cerr<<__FILE__<<endl;
cerr<<"------------------"<<endl; cerr<<"------------------"<<endl;
@ -587,38 +596,40 @@ void FocusControl::setFocusedWindow(WinClient *client) {
cerr<<"Current Focused window = "<<s_focused_window<<endl; cerr<<"Current Focused window = "<<s_focused_window<<endl;
cerr<<"------------------"<<endl; cerr<<"------------------"<<endl;
#endif // DEBUG #endif // DEBUG
/*
WinClient *old_client = 0; WinClient *old_client = 0;
// Update the old focused client to non focus // 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) { old_client = s_focused_window;
s_focused_window = 0; if (old_client->fbwindow()) {
} else { FluxboxWindow *old_win = old_client->fbwindow();
old_client = s_focused_window;
if (old_client->fbwindow()) { if (!client || client->fbwindow() != old_win)
FluxboxWindow *old_win = old_client->fbwindow(); 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()) { if (client && client->fbwindow() && !client->fbwindow()->isIconic()) {
// screen should be ok // screen should be ok
FluxboxWindow *win = client->fbwindow(); FluxboxWindow *win = client->fbwindow();
s_focused_window = client; // update focused window 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 win->setFocusFlag(true); // set focus flag
} else } else
s_focused_window = 0; 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 ////////////////////// FocusControl RESOURCES

View file

@ -96,7 +96,8 @@ public:
void removeClient(WinClient &client); void removeClient(WinClient &client);
static void revertFocus(BScreen &screen); 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 void setFocusedWindow(WinClient *focus_to);
static WinClient *focusedWindow() { return s_focused_window; } static WinClient *focusedWindow() { return s_focused_window; }
private: private:

View file

@ -34,6 +34,7 @@
#include "BoolMenuItem.hh" #include "BoolMenuItem.hh"
#include "CommandParser.hh" #include "CommandParser.hh"
#include "WinClient.hh" #include "WinClient.hh"
#include "FocusControl.hh"
#include "FbTk/I18n.hh" #include "FbTk/I18n.hh"
#include "FbTk/Menu.hh" #include "FbTk/Menu.hh"
@ -948,7 +949,7 @@ void IconbarTool::addList(std::list<FluxboxWindow *> &winlist) {
} }
void IconbarTool::timedRender() { void IconbarTool::timedRender() {
WinClient *client = Fluxbox::instance()->getFocusedWindow(); WinClient *client = FocusControl::focusedWindow();
if (client == 0 || client->fbwindow() == 0) if (client == 0 || client->fbwindow() == 0)
return; return;

View file

@ -925,7 +925,7 @@ void BScreen::changeWorkspaceID(unsigned int id) {
FbTk::App::instance()->sync(false); FbTk::App::instance()->sync(false);
WinClient *focused_client = Fluxbox::instance()->getFocusedWindow(); WinClient *focused_client = FocusControl::focusedWindow();
FluxboxWindow *focused = 0; FluxboxWindow *focused = 0;
if (focused_client) if (focused_client)
focused = focused_client->fbwindow(); focused = focused_client->fbwindow();
@ -966,7 +966,7 @@ void BScreen::changeWorkspaceID(unsigned int id) {
if (focused && (focused->isStuck() || focused->isMoving())) if (focused && (focused->isStuck() || focused->isMoving()))
focused->setInputFocus(); focused->setInputFocus();
else else
Fluxbox::instance()->revertFocus(*this); FocusControl::revertFocus(*this);
if (focused && focused->isMoving()) if (focused && focused->isMoving())
focused->resumeMoving(); focused->resumeMoving();
@ -982,7 +982,7 @@ void BScreen::sendToWorkspace(unsigned int id, FluxboxWindow *win, bool changeWS
return; return;
if (!win) { if (!win) {
WinClient *client = Fluxbox::instance()->getFocusedWindow(); WinClient *client = FocusControl::focusedWindow();
if (client) if (client)
win = client->fbwindow(); win = client->fbwindow();
} }
@ -1039,8 +1039,8 @@ void BScreen::addNetizen(Window win) {
} }
} }
Window f = ((Fluxbox::instance()->getFocusedWindow()) ? Window f = ((FocusControl::focusedWindow()) ?
Fluxbox::instance()->getFocusedWindow()->window() : None); FocusControl::focusedWindow()->window() : None);
net->sendWindowFocus(f); net->sendWindowFocus(f);
} }
@ -1075,8 +1075,8 @@ void BScreen::updateNetizenWorkspaceCount() {
void BScreen::updateNetizenWindowFocus() { void BScreen::updateNetizenWindowFocus() {
Window f = ((Fluxbox::instance()->getFocusedWindow()) ? Window f = ((FocusControl::focusedWindow()) ?
Fluxbox::instance()->getFocusedWindow()->window() : None); FocusControl::focusedWindow()->window() : None);
for_each(m_netizen_list.begin(), for_each(m_netizen_list.begin(),
m_netizen_list.end(), m_netizen_list.end(),
bind2nd(mem_fun(&Netizen::sendWindowFocus), f)); bind2nd(mem_fun(&Netizen::sendWindowFocus), f));

View file

@ -622,7 +622,7 @@ void FluxboxWindow::attachClient(WinClient &client, int x, int y) {
// reparent client win to this frame // reparent client win to this frame
frame().setClientWindow(client); frame().setClientWindow(client);
WinClient *was_focused = 0; 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 // get the current window on the end of our client list
Window leftwin = None; Window leftwin = None;

View file

@ -32,6 +32,7 @@
#include "WinClient.hh" #include "WinClient.hh"
#include "FbWinFrame.hh" #include "FbWinFrame.hh"
#include "WindowCmd.hh" #include "WindowCmd.hh"
#include "FocusControl.hh"
#include "FbTk/I18n.hh" #include "FbTk/I18n.hh"
#include "FbTk/MenuItem.hh" #include "FbTk/MenuItem.hh"
@ -207,7 +208,7 @@ int Workspace::removeWindow(FluxboxWindow *w, bool still_alive) {
} }
if (w->isFocused() && still_alive) 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 // we don't remove it from the layermanager, as it may be being moved
Windows::iterator erase_it = remove(m_windowlist.begin(), Windows::iterator erase_it = remove(m_windowlist.begin(),

View file

@ -29,6 +29,7 @@
#include "Screen.hh" #include "Screen.hh"
#include "fluxbox.hh" #include "fluxbox.hh"
#include "WinClient.hh" #include "WinClient.hh"
#include "FocusControl.hh"
#include "FbTk/KeyUtil.hh" #include "FbTk/KeyUtil.hh"
@ -92,7 +93,7 @@ void DirFocusCmd::execute() {
if (screen == 0) if (screen == 0)
return; return;
WinClient *client = Fluxbox::instance()->getFocusedWindow(); WinClient *client = FocusControl::focusedWindow();
if (client == 0 || client->fbwindow() == 0) if (client == 0 || client->fbwindow() == 0)
return; return;

View file

@ -224,7 +224,7 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"), 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_auto_raise_delay(m_resourcemanager, 250, "session.autoRaiseDelay", "Session.AutoRaiseDelay"),
m_rc_use_mod1(m_resourcemanager, true, "session.useMod1", "Session.UseMod1"), 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_mousescreen(0),
m_keyscreen(0), m_keyscreen(0),
m_watching_screen(0), m_watch_keyrelease(0), m_watching_screen(0), m_watch_keyrelease(0),
@ -511,7 +511,7 @@ int Fluxbox::initScreen(int scrnr) {
(*it).first->initForScreen(*screen); (*it).first->initForScreen(*screen);
} }
revertFocus(*screen); // make sure focus style is correct FocusControl::revertFocus(*screen); // make sure focus style is correct
#ifdef SLIT #ifdef SLIT
if (screen->slit()) if (screen->slit())
screen->slit()->show(); screen->slit()->show();
@ -694,7 +694,7 @@ void Fluxbox::handleEvent(XEvent * const e) {
} }
if (screen != 0) if (screen != 0)
revertFocus(*screen); FocusControl::revertFocus(*screen);
} }
// try FbTk::EventHandler first // try FbTk::EventHandler first
@ -870,8 +870,8 @@ void Fluxbox::handleEvent(XEvent * const e) {
e->xfocus.detail == NotifyInferior) e->xfocus.detail == NotifyInferior)
break; break;
WinClient *winclient = searchWindow(e->xfocus.window); WinClient *winclient = searchWindow(e->xfocus.window);
if (winclient && m_focused_window != winclient) if (winclient && FocusControl::focusedWindow() != winclient)
setFocusedWindow(winclient); FocusControl::setFocusedWindow(winclient);
} break; } break;
case FocusOut:{ case FocusOut:{
@ -886,11 +886,11 @@ void Fluxbox::handleEvent(XEvent * const e) {
#ifdef DEBUG #ifdef DEBUG
cerr<<__FILE__<<"("<<__FUNCTION__<<") Focus out is not a FluxboxWindow !!"<<endl; cerr<<__FILE__<<"("<<__FUNCTION__<<") Focus out is not a FluxboxWindow !!"<<endl;
#endif // DEBUG #endif // DEBUG
} else if (winclient && winclient == m_focused_window && } else if (winclient && winclient == FocusControl::focusedWindow() &&
(winclient->fbwindow() == 0 (winclient->fbwindow() == 0
|| !winclient->fbwindow()->isMoving())) || !winclient->fbwindow()->isMoving()))
// we don't unfocus a moving window // we don't unfocus a moving window
setFocusedWindow(0); FocusControl::setFocusedWindow(0);
} }
break; break;
case ClientMessage: case ClientMessage:
@ -1224,8 +1224,8 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
// make sure each workspace get this // make sure each workspace get this
BScreen &scr = win.screen(); BScreen &scr = win.screen();
scr.removeWindow(&win); scr.removeWindow(&win);
if (m_focused_window == &win.winClient()) if (FocusControl::focusedWindow() == &win.winClient())
m_focused_window = 0; FocusControl::setFocusedWindow(0);
} else if ((&(win.workspaceSig())) == changedsub) { // workspace signal } else if ((&(win.workspaceSig())) == changedsub) { // workspace signal
for (AtomHandlerContainerIt it= m_atomhandler.begin(); for (AtomHandlerContainerIt it= m_atomhandler.begin();
@ -1297,12 +1297,12 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
// This is where we revert focus on window close // This is where we revert focus on window close
// NOWHERE ELSE!!! // NOWHERE ELSE!!!
if (m_focused_window == &client) if (FocusControl::focusedWindow() == &client)
unfocusWindow(client); FocusControl::unfocusWindow(client);
// failed to revert focus? // failed to revert focus?
if (m_focused_window == &client) if (FocusControl::focusedWindow() == &client)
m_focused_window = 0; FocusControl::setFocusedWindow(0);
} }
} }
@ -1796,73 +1796,22 @@ void Fluxbox::timed_reconfigure() {
m_reconfigure_wait = m_reread_menu_wait = false; m_reconfigure_wait = m_reread_menu_wait = false;
} }
// set focused window bool Fluxbox::validateClient(const WinClient *client) const {
void Fluxbox::setFocusedWindow(WinClient *client) { WinClientMap::const_iterator it =
// already focused find_if(m_window_search.begin(),
if (m_focused_window == client) { m_window_search.end(),
#ifdef DEBUG Compose(bind2nd(equal_to<WinClient *>(), client),
cerr<<"Focused window already win"<<endl; Select2nd<WinClientMap::value_type>()));
#endif // DEBUG return it != m_window_search.end();
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;
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) { if (screen != 0) {
screen->updateNetizenWindowFocus(); screen->updateNetizenWindowFocus();
for (AtomHandlerContainerIt it= m_atomhandler.begin(); for (AtomHandlerContainerIt it= m_atomhandler.begin();
it != m_atomhandler.end(); it++) { it != m_atomhandler.end(); it++) {
(*it).first->updateFocusedWindow(*screen, (m_focused_window ? (*it).first->updateFocusedWindow(*screen, (FocusControl::focusedWindow() ?
m_focused_window->window() : FocusControl::focusedWindow()->window() :
0)); 0));
} }
} }
@ -1875,88 +1824,6 @@ void Fluxbox::setFocusedWindow(WinClient *client) {
} }
} }
/**
* 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) { void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) {
if (mods == 0) { if (mods == 0) {

View file

@ -89,6 +89,8 @@ public:
/// main event loop /// main event loop
void eventLoop(); void eventLoop();
bool validateWindow(Window win) const; bool validateWindow(Window win) const;
bool validateClient(const WinClient *client) const;
void grab(); void grab();
void ungrab(); void ungrab();
Keys *keys() { return m_key.get(); } Keys *keys() { return m_key.get(); }
@ -97,7 +99,6 @@ public:
// Not currently implemented until we decide how it'll be used // Not currently implemented until we decide how it'll be used
//WinClient *searchGroup(Window); //WinClient *searchGroup(Window);
WinClient *searchWindow(Window); WinClient *searchWindow(Window);
WinClient *getFocusedWindow() { return m_focused_window; }
int initScreen(int screen_nr); int initScreen(int screen_nr);
BScreen *searchScreen(Window w); BScreen *searchScreen(Window w);
@ -134,6 +135,7 @@ public:
// class to store layer numbers (special Resource type) // class to store layer numbers (special Resource type)
// we have a special resource type because we need to be able to name certain layers // we have a special resource type because we need to be able to name certain layers
// a Resource<int> wouldn't allow this // a Resource<int> wouldn't allow this
class Layer { class Layer {
public: public:
explicit Layer(int i) : m_num(i) {}; explicit Layer(int i) : m_num(i) {};
@ -166,10 +168,6 @@ public:
void watchKeyRelease(BScreen &screen, unsigned int mods); 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 shutdown();
void load_rc(BScreen &scr); void load_rc(BScreen &scr);
void loadRootCommand(BScreen &scr); void loadRootCommand(BScreen &scr);
@ -200,6 +198,12 @@ public:
/// handle any system signal sent to the application /// handle any system signal sent to the application
void handleSignal(int signum); void handleSignal(int signum);
void update(FbTk::Subject *changed); 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(FluxboxWindow &win);
void attachSignals(WinClient &winclient); void attachSignals(WinClient &winclient);
@ -227,7 +231,7 @@ public:
// screen we are watching for modifier changes // screen we are watching for modifier changes
BScreen *watchingScreen() { return m_watching_screen; } BScreen *watchingScreen() { return m_watching_screen; }
const XEvent &lastEvent() const { return m_last_event; } const XEvent &lastEvent() const { return m_last_event; }
private: private:
typedef struct MenuTimestamp { typedef struct MenuTimestamp {
@ -292,7 +296,6 @@ private:
typedef std::list<BScreen *> ScreenList; typedef std::list<BScreen *> ScreenList;
ScreenList m_screen_list; ScreenList m_screen_list;
WinClient *m_focused_window;
FluxboxWindow *m_masked_window; FluxboxWindow *m_masked_window;
BScreen *m_mousescreen, *m_keyscreen; BScreen *m_mousescreen, *m_keyscreen;