aboutsummaryrefslogtreecommitdiff
path: root/src/fluxbox.cc
diff options
context:
space:
mode:
authorfluxgen <fluxgen>2006-02-18 20:19:22 (GMT)
committerfluxgen <fluxgen>2006-02-18 20:19:22 (GMT)
commit5ceacc65925f597180c918fcaa2a8171c42cbcdd (patch)
tree1cee0d151c5368ee69bf4e0e432d0f7f6af37b38 /src/fluxbox.cc
parentf53c93e5e0add69771204056550d07b4fee4efef (diff)
downloadfluxbox_pavel-5ceacc65925f597180c918fcaa2a8171c42cbcdd.zip
fluxbox_pavel-5ceacc65925f597180c918fcaa2a8171c42cbcdd.tar.bz2
moved all focus handling to FocusControl
Diffstat (limited to 'src/fluxbox.cc')
-rw-r--r--src/fluxbox.cc181
1 files changed, 24 insertions, 157 deletions
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index cc9bbb2..d2759d0 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -224,7 +224,7 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
224 m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"), 224 m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"),
225 m_rc_auto_raise_delay(m_resourcemanager, 250, "session.autoRaiseDelay", "Session.AutoRaiseDelay"), 225 m_rc_auto_raise_delay(m_resourcemanager, 250, "session.autoRaiseDelay", "Session.AutoRaiseDelay"),
226 m_rc_use_mod1(m_resourcemanager, true, "session.useMod1", "Session.UseMod1"), 226 m_rc_use_mod1(m_resourcemanager, true, "session.useMod1", "Session.UseMod1"),
227 m_focused_window(0), m_masked_window(0), 227 m_masked_window(0),
228 m_mousescreen(0), 228 m_mousescreen(0),
229 m_keyscreen(0), 229 m_keyscreen(0),
230 m_watching_screen(0), m_watch_keyrelease(0), 230 m_watching_screen(0), m_watch_keyrelease(0),
@@ -511,7 +511,7 @@ int Fluxbox::initScreen(int scrnr) {
511 (*it).first->initForScreen(*screen); 511 (*it).first->initForScreen(*screen);
512 } 512 }
513 513
514 revertFocus(*screen); // make sure focus style is correct 514 FocusControl::revertFocus(*screen); // make sure focus style is correct
515#ifdef SLIT 515#ifdef SLIT
516 if (screen->slit()) 516 if (screen->slit())
517 screen->slit()->show(); 517 screen->slit()->show();
@@ -694,7 +694,7 @@ void Fluxbox::handleEvent(XEvent * const e) {
694 } 694 }
695 695
696 if (screen != 0) 696 if (screen != 0)
697 revertFocus(*screen); 697 FocusControl::revertFocus(*screen);
698 } 698 }
699 699
700 // try FbTk::EventHandler first 700 // try FbTk::EventHandler first
@@ -870,8 +870,8 @@ void Fluxbox::handleEvent(XEvent * const e) {
870 e->xfocus.detail == NotifyInferior) 870 e->xfocus.detail == NotifyInferior)
871 break; 871 break;
872 WinClient *winclient = searchWindow(e->xfocus.window); 872 WinClient *winclient = searchWindow(e->xfocus.window);
873 if (winclient && m_focused_window != winclient) 873 if (winclient && FocusControl::focusedWindow() != winclient)
874 setFocusedWindow(winclient); 874 FocusControl::setFocusedWindow(winclient);
875 875
876 } break; 876 } break;
877 case FocusOut:{ 877 case FocusOut:{
@@ -886,11 +886,11 @@ void Fluxbox::handleEvent(XEvent * const e) {
886#ifdef DEBUG 886#ifdef DEBUG
887 cerr<<__FILE__<<"("<<__FUNCTION__<<") Focus out is not a FluxboxWindow !!"<<endl; 887 cerr<<__FILE__<<"("<<__FUNCTION__<<") Focus out is not a FluxboxWindow !!"<<endl;
888#endif // DEBUG 888#endif // DEBUG
889 } else if (winclient && winclient == m_focused_window && 889 } else if (winclient && winclient == FocusControl::focusedWindow() &&
890 (winclient->fbwindow() == 0 890 (winclient->fbwindow() == 0
891 || !winclient->fbwindow()->isMoving())) 891 || !winclient->fbwindow()->isMoving()))
892 // we don't unfocus a moving window 892 // we don't unfocus a moving window
893 setFocusedWindow(0); 893 FocusControl::setFocusedWindow(0);
894 } 894 }
895 break; 895 break;
896 case ClientMessage: 896 case ClientMessage:
@@ -1224,8 +1224,8 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
1224 // make sure each workspace get this 1224 // make sure each workspace get this
1225 BScreen &scr = win.screen(); 1225 BScreen &scr = win.screen();
1226 scr.removeWindow(&win); 1226 scr.removeWindow(&win);
1227 if (m_focused_window == &win.winClient()) 1227 if (FocusControl::focusedWindow() == &win.winClient())
1228 m_focused_window = 0; 1228 FocusControl::setFocusedWindow(0);
1229 1229
1230 } else if ((&(win.workspaceSig())) == changedsub) { // workspace signal 1230 } else if ((&(win.workspaceSig())) == changedsub) { // workspace signal
1231 for (AtomHandlerContainerIt it= m_atomhandler.begin(); 1231 for (AtomHandlerContainerIt it= m_atomhandler.begin();
@@ -1297,12 +1297,12 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
1297 1297
1298 // This is where we revert focus on window close 1298 // This is where we revert focus on window close
1299 // NOWHERE ELSE!!! 1299 // NOWHERE ELSE!!!
1300 if (m_focused_window == &client) 1300 if (FocusControl::focusedWindow() == &client)
1301 unfocusWindow(client); 1301 FocusControl::unfocusWindow(client);
1302 1302
1303 // failed to revert focus? 1303 // failed to revert focus?
1304 if (m_focused_window == &client) 1304 if (FocusControl::focusedWindow() == &client)
1305 m_focused_window = 0; 1305 FocusControl::setFocusedWindow(0);
1306 } 1306 }
1307} 1307}
1308 1308
@@ -1796,73 +1796,22 @@ void Fluxbox::timed_reconfigure() {
1796 m_reconfigure_wait = m_reread_menu_wait = false; 1796 m_reconfigure_wait = m_reread_menu_wait = false;
1797} 1797}
1798 1798
1799// set focused window 1799bool Fluxbox::validateClient(const WinClient *client) const {
1800void Fluxbox::setFocusedWindow(WinClient *client) { 1800 WinClientMap::const_iterator it =
1801 // already focused 1801 find_if(m_window_search.begin(),
1802 if (m_focused_window == client) { 1802 m_window_search.end(),
1803#ifdef DEBUG 1803 Compose(bind2nd(equal_to<WinClient *>(), client),
1804 cerr<<"Focused window already win"<<endl; 1804 Select2nd<WinClientMap::value_type>()));
1805#endif // DEBUG 1805 return it != m_window_search.end();
1806 return; 1806}
1807 }
1808#ifdef DEBUG
1809 cerr<<"Setting Focused window = "<<client<<endl;
1810 if (client != 0 && client->fbwindow() != 0)
1811 cerr<<"title: "<<client->fbwindow()->title()<<endl;
1812 cerr<<"Current Focused window = "<<m_focused_window<<endl;
1813 cerr<<"------------------"<<endl;
1814#endif // DEBUG
1815 BScreen *old_screen = 0, *screen = 0;
1816 WinClient *old_client = 0;
1817
1818 if (m_focused_window != 0) {
1819 // check if m_focused_window is valid
1820 WinClientMap::iterator it = find_if(m_window_search.begin(),
1821 m_window_search.end(),
1822 Compose(bind2nd(equal_to<WinClient *>(), m_focused_window),
1823 Select2nd<WinClientMap::value_type>()));
1824
1825 // if not found...
1826 if (it == m_window_search.end()) {
1827 m_focused_window = 0;
1828 } else {
1829 old_client = m_focused_window;
1830 old_screen = &old_client->screen();
1831
1832 if (old_client->fbwindow()) {
1833 FluxboxWindow *old_win = old_client->fbwindow();
1834
1835 if (!client || client->fbwindow() != old_win)
1836 old_win->setFocusFlag(false);
1837 }
1838 }
1839 }
1840
1841 if (client && client->fbwindow() && !client->fbwindow()->isIconic()) {
1842 FluxboxWindow *win = client->fbwindow();
1843 // make sure we have a valid win pointer with a valid screen
1844 ScreenList::iterator winscreen =
1845 std::find(m_screen_list.begin(), m_screen_list.end(),
1846 &client->screen());
1847 if (winscreen == m_screen_list.end()) {
1848 m_focused_window = 0; // the window pointer wasn't valid, mark no window focused
1849 } else {
1850 screen = *winscreen;
1851 m_focused_window = client; // update focused window
1852 win->setCurrentClient(*client, false); // don't setinputfocus
1853 win->setFocusFlag(true); // set focus flag
1854 }
1855
1856 } else
1857 m_focused_window = 0;
1858
1859 1807
1808void Fluxbox::updateFocusedWindow(BScreen *screen, BScreen *old_screen) {
1860 if (screen != 0) { 1809 if (screen != 0) {
1861 screen->updateNetizenWindowFocus(); 1810 screen->updateNetizenWindowFocus();
1862 for (AtomHandlerContainerIt it= m_atomhandler.begin(); 1811 for (AtomHandlerContainerIt it= m_atomhandler.begin();
1863 it != m_atomhandler.end(); it++) { 1812 it != m_atomhandler.end(); it++) {
1864 (*it).first->updateFocusedWindow(*screen, (m_focused_window ? 1813 (*it).first->updateFocusedWindow(*screen, (FocusControl::focusedWindow() ?
1865 m_focused_window->window() : 1814 FocusControl::focusedWindow()->window() :
1866 0)); 1815 0));
1867 } 1816 }
1868 } 1817 }
@@ -1875,88 +1824,6 @@ void Fluxbox::setFocusedWindow(WinClient *client) {
1875 } 1824 }
1876} 1825}
1877 1826
1878/**
1879 * This function is called whenever we aren't quite sure what
1880 * focus is meant to be, it'll make things right ;-)
1881 * last_focused is set to something if we want to make use of the
1882 * previously focused window (it must NOT be set focused now, it
1883 * is probably dying).
1884 *
1885 * ignore_event means that it ignores the given event until
1886 * it gets a focusIn
1887 */
1888void Fluxbox::revertFocus(BScreen &screen) {
1889 // Relevant resources:
1890 // resource.focus_last = whether we focus last focused when changing workspace
1891 // BScreen::FocusModel = sloppy, click, whatever
1892 WinClient *next_focus = screen.focusControl().lastFocusedWindow(screen.currentWorkspaceID());
1893
1894 // if setting focus fails, or isn't possible, fallback correctly
1895 if (!(next_focus && next_focus->fbwindow() &&
1896 next_focus->fbwindow()->setCurrentClient(*next_focus, true))) {
1897 setFocusedWindow(0); // so we don't get dangling m_focused_window pointer
1898 switch (screen.focusControl().focusModel()) {
1899 case FocusControl::MOUSEFOCUS:
1900 XSetInputFocus(FbTk::App::instance()->display(),
1901 PointerRoot, None, CurrentTime);
1902 break;
1903 case FocusControl::CLICKFOCUS:
1904 screen.rootWindow().setInputFocus(RevertToPointerRoot, CurrentTime);
1905 break;
1906 }
1907 }
1908}
1909
1910/*
1911 * Like revertFocus, but specifically related to this window (transients etc)
1912 * if full_revert, we fallback to a full revertFocus if we can't find anything
1913 * local to the client.
1914 * If unfocus_frame is true, we won't focus anything in the same frame
1915 * as the client.
1916 *
1917 * So, we first prefer to choose a transient parent, then the last
1918 * client in this window, and if no luck (or unfocus_frame), then
1919 * we just use the normal revertFocus on the screen.
1920 *
1921 * assumption: client has focus
1922 */
1923void Fluxbox::unfocusWindow(WinClient &client, bool full_revert, bool unfocus_frame) {
1924 // go up the transient tree looking for a focusable window
1925
1926 FluxboxWindow *fbwin = client.fbwindow();
1927 if (fbwin == 0)
1928 unfocus_frame = false;
1929
1930 WinClient *trans_parent = client.transientFor();
1931 while (trans_parent) {
1932 if (trans_parent->fbwindow() && // can't focus if no fbwin
1933 (!unfocus_frame || trans_parent->fbwindow() != fbwin) && // can't be this window
1934 trans_parent->fbwindow()->isVisible() &&
1935 trans_parent->fbwindow()->setCurrentClient(*trans_parent, m_focused_window == &client)) {
1936 return;
1937 }
1938 trans_parent = trans_parent->transientFor();
1939 }
1940
1941 if (fbwin == 0)
1942 return; // nothing more we can do
1943
1944 BScreen &screen = fbwin->screen();
1945
1946 if (!unfocus_frame) {
1947 WinClient *last_focus = screen.focusControl().lastFocusedWindow(*fbwin, &client);
1948 if (last_focus != 0 &&
1949 fbwin->setCurrentClient(*last_focus, m_focused_window == &client)) {
1950 return;
1951 }
1952 }
1953
1954 if (full_revert && m_focused_window == &client)
1955 revertFocus(screen);
1956
1957}
1958
1959
1960void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) { 1827void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) {
1961 1828
1962 if (mods == 0) { 1829 if (mods == 0) {