From cc2f023a22db212b4097d7756379bb6b9e866b11 Mon Sep 17 00:00:00 2001 From: rathnor <rathnor> Date: Sat, 22 Feb 2003 15:10:43 +0000 Subject: fix focus models for new event handler and Resource setup --- ChangeLog | 3 ++ src/Screen.cc | 46 ++++++++++++---------- src/Screen.hh | 18 +++++---- src/Window.cc | 66 ++++++++++++++++++++++++++++--- src/Window.hh | 4 +- src/fluxbox.cc | 120 +++++++++++++++++++++------------------------------------ src/fluxbox.hh | 6 ++- 7 files changed, 149 insertions(+), 114 deletions(-) diff --git a/ChangeLog b/ChangeLog index 10df0e8..2619fa2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ (Format: Year/Month/Day) Changes for 0.1.15: +*03/02/22: + * Fixed sloppy focus to use new event handler model (Simon) + Screen.hh/cc Window.hh/cc fluxbox.hh/cc *03/02/20: * Fixed a size bug without titlebar (Henrik) Window.cc, FbWinFrame.cc diff --git a/src/Screen.cc b/src/Screen.cc index ee32f56..9ca7859 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.cc,v 1.112 2003/02/20 23:31:13 fluxgen Exp $ +// $Id: Screen.cc,v 1.113 2003/02/22 15:10:43 rathnor Exp $ #include "Screen.hh" @@ -139,22 +139,21 @@ FbTk::Menu *createMenuFromScreen(BScreen &screen) { return menu; } -/* -class WindowLayerMenuItem : public FbTk::MenuItem { +class FocusModelMenuItem : public FbTk::MenuItem { public: - WindowLayerMenuItem(const char *label, FluxboxWindow &win, int layernum): - FbTk::MenuItem(label), m_window(win), m_layernum(layernum) { + FocusModelMenuItem(const char *label, BScreen &screen, Fluxbox::FocusModel model, FbTk::RefCount<FbTk::Command> &cmd): + FbTk::MenuItem(label, cmd), m_screen(screen), m_focusmodel(model) { } - bool isEnabled() const { return m_window.getLayerNum() != m_layernum; } + bool isEnabled() const { return m_screen.getFocusModel() != m_focusmodel; } void click(int button, int time) { - m_window.moveToLayer(m_layernum); + m_screen.saveFocusModel(m_focusmodel); + FbTk::MenuItem::click(button, time); } private: - FluxboxWindow &m_window; - int m_layernum; + BScreen &m_screen; + Fluxbox::FocusModel m_focusmodel; }; -*/ }; // End anonymous namespace @@ -363,6 +362,7 @@ BScreen::ScreenResource::ScreenResource(ResourceManager &rm, focus_new(rm, true, scrname+".focusNewWindows", altscrname+".FocusNewWindows"), antialias(rm, false, scrname+".antialias", altscrname+".Antialias"), rootcommand(rm, "", scrname+".rootCommand", altscrname+".RootCommand"), + focus_model(rm, Fluxbox::CLICKTOFOCUS, scrname+".focusModel", altscrname+".FocusModel"), workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"), toolbar_width_percent(rm, 65, scrname+".toolbar.widthPercent", altscrname+".Toolbar.WidthPercent"), edge_snap_threshold(rm, 0, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"), @@ -616,7 +616,7 @@ BScreen::BScreen(ResourceManager &rm, } } - if (! resource.sloppy_focus) { + if (! isSloppyFocus()) { XSetInputFocus(disp, m_toolbar->getWindowID(), RevertToParent, CurrentTime); } @@ -1733,21 +1733,27 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { // create focus menu FbTk::Menu *focus_menu = createMenuFromScreen(*this); - /* focus_menu->insert(new BoolMenuItem(i18n->getMessage( - ConfigmenuSet, ConfigmenuClickToFocus, - "Click To Focus"),*/ - focus_menu->insert(new BoolMenuItem(i18n->getMessage( + focus_menu->insert(new FocusModelMenuItem(i18n->getMessage( ConfigmenuSet, + ConfigmenuClickToFocus, + "Click To Focus"), + *this, + Fluxbox::CLICKTOFOCUS, + save_and_reconfigure)); + focus_menu->insert(new FocusModelMenuItem(i18n->getMessage( + ConfigmenuSet, ConfigmenuSloppyFocus, "Sloppy Focus"), - resource.sloppy_focus, - save_and_reconfigure)); - focus_menu->insert(new BoolMenuItem(i18n->getMessage( + *this, + Fluxbox::SLOPPYFOCUS, + save_and_reconfigure)); + focus_menu->insert(new FocusModelMenuItem(i18n->getMessage( ConfigmenuSet, ConfigmenuSemiSloppyFocus, "Semi Sloppy Focus"), - resource.semi_sloppy_focus, - save_and_reconfigure)); + *this, + Fluxbox::SEMISLOPPYFOCUS, + save_and_reconfigure)); focus_menu->insert(new BoolMenuItem(i18n->getMessage( ConfigmenuSet, ConfigmenuAutoRaise, diff --git a/src/Screen.hh b/src/Screen.hh index 1b833d4..a30ca40 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.hh,v 1.69 2003/02/20 23:33:08 fluxgen Exp $ +// $Id: Screen.hh,v 1.70 2003/02/22 15:10:43 rathnor Exp $ #ifndef SCREEN_HH #define SCREEN_HH @@ -79,8 +79,8 @@ public: ~BScreen(); inline bool doToolbarAutoHide() const { return *resource.toolbar_auto_hide; } - inline bool isSloppyFocus() const { return resource.sloppy_focus; } - inline bool isSemiSloppyFocus() const { return resource.semi_sloppy_focus; } + inline bool isSloppyFocus() const { return (*resource.focus_model == Fluxbox::SLOPPYFOCUS); } + inline bool isSemiSloppyFocus() const { return (*resource.focus_model == Fluxbox::SEMISLOPPYFOCUS); } inline bool isRootColormapInstalled() const { return root_colormap_installed; } inline bool isScreenManaged() const { return managed; } inline bool isTabRotateVertical() const { return *resource.tab_rotate_vertical; } @@ -104,6 +104,7 @@ public: FbTk::Menu * const getRootmenu() { return m_rootmenu.get(); } inline const std::string &getRootCommand() const { return *resource.rootcommand; } + inline Fluxbox::FocusModel getFocusModel() const { return *resource.focus_model; } inline bool doSlitAutoHide() const { return resource.slit_auto_hide; } #ifdef SLIT @@ -188,9 +189,10 @@ public: inline void setRootColormapInstalled(Bool r) { root_colormap_installed = r; } inline void saveRootCommand(std::string rootcmd) { *resource.rootcommand = rootcmd; } - inline void saveSloppyFocus(bool s) { resource.sloppy_focus = s; } - inline void saveSemiSloppyFocus(bool s) { resource.semi_sloppy_focus = s; } - inline void saveAutoRaise(bool a) { resource.auto_raise = a; } + inline void saveFocusModel(Fluxbox::FocusModel model) { resource.focus_model = model; } + //DEL inline void saveSloppyFocus(bool s) { resource.sloppy_focus = s; } + //DEL inline void saveSemiSloppyFocus(bool s) { resource.semi_sloppy_focus = s; } + //DEL inline void saveAutoRaise(bool a) { resource.auto_raise = a; } inline void saveWorkspaces(int w) { *resource.workspaces = w; } inline void saveToolbarAutoHide(bool r) { *resource.toolbar_auto_hide = r; } inline void saveToolbarWidthPercent(int w) { *resource.toolbar_width_percent = w; } @@ -382,8 +384,8 @@ private: focus_last, focus_new, antialias; Resource<std::string> rootcommand; - bool auto_raise, sloppy_focus, semi_sloppy_focus, - ordered_dither; + Resource<Fluxbox::FocusModel> focus_model; + bool auto_raise, ordered_dither; Resource<int> workspaces, toolbar_width_percent, edge_snap_threshold, tab_width, tab_height; Resource<Fluxbox::Layer> slit_layernum, toolbar_layernum; diff --git a/src/Window.cc b/src/Window.cc index 73afefc..ec0d7f3 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.cc,v 1.122 2003/02/20 23:17:36 fluxgen Exp $ +// $Id: Window.cc,v 1.123 2003/02/22 15:10:43 rathnor Exp $ #include "Window.hh" @@ -93,6 +93,26 @@ void grabButton(Display *display, unsigned int button, } +// X event scanner for enter/leave notifies - adapted from twm +typedef struct scanargs { + Window w; + Bool leave, inferior, enter; +} scanargs; + +// look for valid enter or leave events (that may invalidate the earlier one we are interested in) +static Bool queueScanner(Display *, XEvent *e, char *args) { + if ((e->type == LeaveNotify) && + (e->xcrossing.window == ((scanargs *) args)->w) && + (e->xcrossing.mode == NotifyNormal)) { + ((scanargs *) args)->leave = True; + ((scanargs *) args)->inferior = (e->xcrossing.detail == NotifyInferior); + } else if ((e->type == EnterNotify) && + (e->xcrossing.mode == NotifyUngrab)) + ((scanargs *) args)->enter = True; + + return False; +} + /// raise window and do the same for each transient it holds void raiseFluxboxWindow(FluxboxWindow &win) { @@ -2066,12 +2086,12 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { m_frame.x() < int(me.x_root - button_grab_x - screen->getBorderWidth())) { //warp right new_id = (cur_id + 1) % screen->getCount(); - dx = - me.x_root; + dx = - me.x_root; // move mouse back to x=0 } else if (me.x_root <= warpPad && m_frame.x() > int(me.x_root - button_grab_x - screen->getBorderWidth())) { //warp left new_id = (cur_id - 1 + screen->getCount()) % screen->getCount(); - dx = screen->getWidth() - me.x_root-1; + dx = screen->getWidth() - me.x_root-1; // move mouse to screen width - 1 } if (new_id != cur_id) { @@ -2081,8 +2101,8 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { last_resize_x = me.x_root + dx; - dx += m_frame.x(); // for window in correct position - + // change dx to be relative to window rather than motion event + dx += m_frame.x(); } } @@ -2098,7 +2118,6 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { last_move_x = dx; last_move_y = dy; } else { - moveResize(dx, dy, m_frame.width(), m_frame.height()); } @@ -2154,6 +2173,41 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { } +void FluxboxWindow::enterNotifyEvent(XCrossingEvent &ev) { + + // ignore grab activates, or if we're not visible + if (ev.mode == NotifyGrab || + !isVisible()) { + return; + } + + if (ev.window == getFrameWindow() || + (!getFrameWindow() && ev.window == client.window)) { + if ((screen->isSloppyFocus() || screen->isSemiSloppyFocus()) + && !isFocused()) { + Fluxbox::instance()->grab(); + + // check that there aren't any subsequent leave notify events in the + // X event queue + XEvent dummy; + scanargs sa; + sa.w = ev.window; + sa.enter = sa.leave = False; + XCheckIfEvent(display, &dummy, queueScanner, (char *) &sa); + + if ((!sa.leave || sa.inferior) && setInputFocus()) + installColormap(True); + + Fluxbox::instance()->ungrab(); + } + } +} + +void FluxboxWindow::leaveNotifyEvent(XCrossingEvent &ev) { + if (ev.window == getFrameWindow()) + installColormap(False); +} + // TODO: functions should not be affected by decoration void FluxboxWindow::setDecoration(Decoration decoration) { switch (decoration) { diff --git a/src/Window.hh b/src/Window.hh index f55b307..5535c6e 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.hh,v 1.50 2003/02/18 15:11:11 rathnor Exp $ +// $Id: Window.hh,v 1.51 2003/02/22 15:10:43 rathnor Exp $ #ifndef WINDOW_HH #define WINDOW_HH @@ -173,6 +173,8 @@ public: void exposeEvent(XExposeEvent &ee); void configureRequestEvent(XConfigureRequestEvent &ce); void propertyNotifyEvent(Atom a); + void enterNotifyEvent(XCrossingEvent &ev); + void leaveNotifyEvent(XCrossingEvent &ev); //@} void setDecoration(Decoration decoration); diff --git a/src/fluxbox.cc b/src/fluxbox.cc index be41df1..1cb66a9 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: fluxbox.cc,v 1.97 2003/02/18 15:11:12 rathnor Exp $ +// $Id: fluxbox.cc,v 1.98 2003/02/22 15:10:43 rathnor Exp $ #include "fluxbox.hh" @@ -143,25 +143,6 @@ char *basename (char *s) { #define RC_PATH "fluxbox" #define RC_INIT_FILE "init" - -// X event scanner for enter/leave notifies - adapted from twm -typedef struct scanargs { - Window w; - Bool leave, inferior, enter; -} scanargs; - -static Bool queueScanner(Display *, XEvent *e, char *args) { - if ((e->type == LeaveNotify) && - (e->xcrossing.window == ((scanargs *) args)->w) && - (e->xcrossing.mode == NotifyNormal)) { - ((scanargs *) args)->leave = True; - ((scanargs *) args)->inferior = (e->xcrossing.detail == NotifyInferior); - } else if ((e->type == EnterNotify) && - (e->xcrossing.mode == NotifyUngrab)) - ((scanargs *) args)->enter = True; - - return False; -} //----------------------------------------------------------------- //---- accessors for int, bool, and some enums with Resource ------ //----------------------------------------------------------------- @@ -189,6 +170,19 @@ setFromString(char const *strval) { } template<> +void Resource<Fluxbox::FocusModel>:: +setFromString(char const *strval) { + if (strcasecmp(strval, "SloppyFocus") == 0) + m_value = Fluxbox::SLOPPYFOCUS; + else if (strcasecmp(strval, "SemiSloppyFocus") == 0) + m_value = Fluxbox::SEMISLOPPYFOCUS; + else if (strcasecmp(strval, "ClickToFocus") == 0) + m_value = Fluxbox::CLICKTOFOCUS; + else + setDefaultValue(); +} + +template<> void Resource<Fluxbox::TitlebarList>:: setFromString(char const *strval) { vector<std::string> val; @@ -242,6 +236,21 @@ std::string Resource<std::string>:: getString() { return **this; } template<> +std::string Resource<Fluxbox::FocusModel>:: +getString() { + switch (m_value) { + case Fluxbox::SLOPPYFOCUS: + return string("SloppyFocus"); + case Fluxbox::SEMISLOPPYFOCUS: + return string("SemiSloppyFocus"); + case Fluxbox::CLICKTOFOCUS: + return string("ClickToFocus"); + } + // default string + return string("ClickToFocus"); +} + +template<> std::string Resource<Fluxbox::TitlebarList>:: getString() { string retval; @@ -691,18 +700,7 @@ void Fluxbox::handleEvent(XEvent * const e) { } break; - case MotionNotify: { - last_time = e->xmotion.time; - - FluxboxWindow *win = 0; - Tab *tab = 0; - - if ((win = searchWindow(e->xmotion.window)) !=0) - win->motionNotifyEvent(e->xmotion); - else if ((tab = searchTab(e->xmotion.window)) !=0) - tab->motionNotifyEvent(&e->xmotion); - - } + case MotionNotify: break; case PropertyNotify: { @@ -719,63 +717,26 @@ void Fluxbox::handleEvent(XEvent * const e) { break; case EnterNotify: { last_time = e->xcrossing.time; - BScreen *screen = 0; - FluxboxWindow *win = 0; - Tab *tab = 0; if (e->xcrossing.mode == NotifyGrab) break; - XEvent dummy; - scanargs sa; - sa.w = e->xcrossing.window; - sa.enter = sa.leave = False; - XCheckIfEvent(getXDisplay(), &dummy, queueScanner, (char *) &sa); - if ((e->xcrossing.window == e->xcrossing.root) && (screen = searchScreen(e->xcrossing.window))) { screen->getImageControl()->installRootColormap(); - } else if ((win = searchWindow(e->xcrossing.window))) { - if ((win->getScreen()->isSloppyFocus() || - win->getScreen()->isSemiSloppyFocus()) && - (! win->isFocused()) && (! no_focus)) { - - grab(); - - if (((! sa.leave) || sa.inferior) && win->isVisible() && - win->setInputFocus()) - win->installColormap(True); - ungrab(); - } - } else if ((tab = searchTab(e->xcrossing.window))) { - win = tab->getWindow(); - if (win->getScreen()->isSloppyFocus() && (! win->isFocused()) && - (! no_focus)) { - win->raise(); - - grab(); - - if (((! sa.leave) || sa.inferior) && win->isVisible() && - win->setInputFocus()) - win->installColormap(True); - - ungrab(); - } - } + // if sloppy focus, then remove focus from windows + if (screen->isSloppyFocus() || + screen->isSemiSloppyFocus()) + setFocusedWindow(0); + } } break; case LeaveNotify: { last_time = e->xcrossing.time; - - FluxboxWindow *win = (FluxboxWindow *) 0; - - if ((win = searchWindow(e->xcrossing.window))) - win->installColormap(false); - } break; case Expose: @@ -841,6 +802,7 @@ void Fluxbox::handleButtonEvent(XButtonEvent &be) { FluxboxWindow *win = 0; Tab *tab = 0; + /* if ((win = searchWindow(be.window))) { win->buttonPressEvent(be); @@ -848,7 +810,7 @@ void Fluxbox::handleButtonEvent(XButtonEvent &be) { if (be.button == 1) win->installColormap(True); } - else if ((tab = searchTab(be.window))) { + else*/ if ((tab = searchTab(be.window))) { tab->buttonPressEvent(&be); } else { ScreenList::iterator it = screenList.begin(); @@ -1782,6 +1744,8 @@ void Fluxbox::save_rc() { placement.c_str()); XrmPutLineResource(&new_blackboxrc, rc_string); + //TODO +/* std::string focus_mode; if (screen->isSloppyFocus() && screen->doAutoRaise()) focus_mode = "AutoRaiseSloppyFocus"; @@ -1797,7 +1761,7 @@ void Fluxbox::save_rc() { sprintf(rc_string, "session.screen%d.focusModel: %s", screen_number, focus_mode.c_str()); XrmPutLineResource(&new_blackboxrc, rc_string); - +*/ // load_rc(screen); // these are static, but may not be saved in the users resource file, // writing these resources will allow the user to edit them at a later @@ -2024,6 +1988,8 @@ void Fluxbox::load_rc(BScreen *screen) { delete [] search; } +//TODO (use Fluxbox::FocusModel enum) + /* sprintf(name_lookup, "session.screen%d.focusModel", screen_number); sprintf(class_lookup, "Session.Screen%d.FocusModel", screen_number); if (XrmGetResource(*database, name_lookup, class_lookup, &value_type, @@ -2058,7 +2024,7 @@ void Fluxbox::load_rc(BScreen *screen) { screen->saveSloppyFocus(true); screen->saveAutoRaise(false); } - + */ sprintf(name_lookup, "session.screen%d.windowPlacement", screen_number); sprintf(class_lookup, "Session.Screen%d.WindowPlacement", screen_number); if (XrmGetResource(*database, name_lookup, class_lookup, &value_type, diff --git a/src/fluxbox.hh b/src/fluxbox.hh index 84aac80..cce734f 100644 --- a/src/fluxbox.hh +++ b/src/fluxbox.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: fluxbox.hh,v 1.43 2003/02/18 15:11:12 rathnor Exp $ +// $Id: fluxbox.hh,v 1.44 2003/02/22 15:10:43 rathnor Exp $ #ifndef FLUXBOX_HH #define FLUXBOX_HH @@ -103,7 +103,9 @@ public: /// obsolete enum Titlebar{SHADE=0, MINIMIZE, MAXIMIZE, CLOSE, STICK, MENU, EMPTY}; - + + enum FocusModel { SLOPPYFOCUS=0, SEMISLOPPYFOCUS, CLICKTOFOCUS }; + inline const std::vector<Fluxbox::Titlebar>& getTitlebarRight() { return *m_rc_titlebar_right; } inline const std::vector<Fluxbox::Titlebar>& getTitlebarLeft() { return *m_rc_titlebar_left; } inline const std::string &getStyleFilename() const { return *m_rc_stylefile; } -- cgit v0.11.2