Changed some *Focus options, just to make some things a bit more clear. the "Sloppy" was always a bit .. unprecise. removed SloppyFocus, SemiSloppyFocus and ClickToFocus options added MouseFocus, ClickFocus, MouseTabFocus, ClickTabFocus - MouseFocus - change the focus to the window under the mouse (almost similar to the 'old' SloppyFocus) - ClickFocus - change the focus to the window the user clicks - MouseTabFocus - change active tabclient to the one under the mouse in titlebar, does NOT change the focus - ClickTabFocus - change active tabclient when clicked onto a tabbutton to achieve former SemiSloppyFocus behavior one needs MouseFocus and ClickTabFocus
@@ -1,5 +1,20 @@
(Format: Year/Month/Day) Changes for 0.9.14: +*05/07/20: + Changed some *Focus options (Mathias) + removed SloppyFocus, SemiSloppyFocus and ClickToFocus options + added MouseFocus, ClickFocus, MouseTabFocus, ClickTabFocus + - MouseFocus - change the focus to the window under the mouse + (almost similar to the 'old' SloppyFocus) + - ClickFocus - change the focus to the window the user clicks + - MouseTabFocus - change active tabclient to the one under the + mouse in titlebar, does NOT change the focus + - ClickTabFocus - change active tabclient when clicked onto a + tabbutton + to achieve former SemiSloppyFocus behavior one needs MouseFocus and + ClickTabFocus + Window.cc Screen.cc/hh ScreenResource.cc FocusModelMenuItem.hh fluxbox.cc + nls/fluxbox-nls.hh and some nls/*/Translation.m *05/07/13: Dragging a tab button from current titlebar onto current client area will detach that client (Mathias)
@@ -60,8 +60,7 @@ 9 Focus New Windows
10 Full Maximization 11 Image Dithering 12 Opaque Window Moving -13 Semi Sloppy Focus -14 Sloppy Focus +14 Mouse Focus 15 Workspace Warping 16 Force Pseudo-Transparency 17 Menu Alpha
@@ -50,7 +50,7 @@
1 Kantenglättung (AntiAliasing) 2 Automatisches Hervorheben 3 Klicken zum Hervorheben -4 Klicken zum Fokussieren +4 Fokus durch Klick 5 Flüchtige (transient) Fenster dekorieren 6 Desktop mit Mausrad wechseln 7 Fenster nach Desktopwechsel fokussieren@@ -60,10 +60,10 @@ 10 Vollständig Maximieren
11 Bild-Dithering 12 Fenster undurchsichtig bewegen 13 Halb-"schlampiger" Fokus -14 "schlampiger" Fokus +14 MausFokus 15 Fenster über Desktopgrenzen verschieben 16 Erzwinge Pseudo-Transparenz -17 Menü Alpha Transparenz +17 Menü Alpha Transparenz 18 Transparenz 19 Alpha Transparenz fokussierter Fenster 20 Alpha Transparenz nicht fokussierter Fenster
@@ -53,7 +53,7 @@ ConfigmenuSet = 4,
ConfigmenuAntiAlias = 1, ConfigmenuAutoRaise = 2, ConfigmenuClickRaises = 3, - ConfigmenuClickToFocus = 4, + ConfigmenuClickFocus = 4, ConfigmenuDecorateTransient = 5, ConfigmenuDesktopWheeling = 6, ConfigmenuFocusLast = 7,@@ -62,8 +62,8 @@ ConfigmenuFocusNew = 9,
ConfigmenuFullMax = 10, ConfigmenuImageDithering = 11, ConfigmenuOpaqueMove = 12, - ConfigmenuSemiSloppyFocus = 13, - ConfigmenuSloppyFocus = 14, +// disabled, obsolete: ConfigmenuSemiSloppyFocus = 13, + ConfigmenuMouseFocus = 14, ConfigmenuWorkspaceWarping = 15, ConfigmenuForcePseudoTrans = 16, ConfigmenuMenuAlpha = 17,
@@ -50,4 +50,24 @@ BScreen &m_screen;
BScreen::FocusModel m_focusmodel; }; +class TabFocusModelMenuItem : public FbTk::MenuItem { +public: + TabFocusModelMenuItem(const char *label, BScreen &screen, + BScreen::TabFocusModel model, + FbTk::RefCount<FbTk::Command> &cmd): + FbTk::MenuItem(label, cmd), m_screen(screen), m_tabfocusmodel(model) { + } + bool isEnabled() const { return m_screen.getTabFocusModel() != m_tabfocusmodel; } + + void click(int button, int time) { + m_screen.saveTabFocusModel(m_tabfocusmodel); + FbTk::MenuItem::click(button, time); + } + +private: + BScreen &m_screen; + BScreen::TabFocusModel m_tabfocusmodel; +}; + + #endif // FOCUSMODELMENUITEM_HH
@@ -176,7 +176,8 @@ decorate_transient(rm, false, scrname+".decorateTransient", altscrname+".DecorateTransient"),
rootcommand(rm, "", scrname+".rootCommand", altscrname+".RootCommand"), resize_model(rm, BOTTOMRESIZE, scrname+".resizeMode", altscrname+".ResizeMode"), windowmenufile(rm, "", scrname+".windowMenu", altscrname+".WindowMenu"), - focus_model(rm, CLICKTOFOCUS, scrname+".focusModel", altscrname+".FocusModel"), + focus_model(rm, CLICKFOCUS, scrname+".focusModel", altscrname+".FocusModel"), + tabfocus_model(rm, CLICKTABFOCUS, scrname+".tabFocusModel", altscrname+".TabFocusModel"), follow_model(rm, IGNORE_OTHER_WORKSPACES, scrname+".followModel", altscrname+".followModel"), workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"), edge_snap_threshold(rm, 0, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"),@@ -1771,15 +1772,16 @@ FbTk::Menu *focus_menu = createMenu(focusmenu_label ? focusmenu_label : "");
#define _FOCUSITEM(a, b, c, d, e) focus_menu->insert(new FocusModelMenuItem(_FBTEXT(a, b, c, d), *this, e, save_and_reconfigure)) - _FOCUSITEM(Configmenu, ClickToFocus, + _FOCUSITEM(Configmenu, ClickFocus, "Click To Focus", "Click to focus", - CLICKTOFOCUS); - _FOCUSITEM(Configmenu, SloppyFocus, - "Sloppy Focus", "Sloppy Focus", - SLOPPYFOCUS); - _FOCUSITEM(Configmenu, SemiSloppyFocus, - "Semi Sloppy Focus", "Semi Sloppy Focus", - SEMISLOPPYFOCUS); + CLICKFOCUS); + _FOCUSITEM(Configmenu, MouseFocus, + "Mouse Focus", "Mouse Focus", + MOUSEFOCUS); + + focus_menu->insert(new TabFocusModelMenuItem("ClickTabFocus", *this, CLICKTABFOCUS, save_and_reconfigure)); + focus_menu->insert(new TabFocusModelMenuItem("MouseTabFocus", *this, MOUSETABFOCUS, save_and_reconfigure)); + #undef _FOCUSITEM focus_menu->insert(new BoolMenuItem(_FBTEXT(Configmenu,
@@ -78,7 +78,8 @@ */
class BScreen : public FbTk::Observer, private FbTk::NotCopyable { public: enum ResizeModel { BOTTOMRESIZE = 0, QUADRANTRESIZE, DEFAULTRESIZE = BOTTOMRESIZE }; - enum FocusModel { SLOPPYFOCUS = 0, SEMISLOPPYFOCUS, CLICKTOFOCUS }; + enum FocusModel { MOUSEFOCUS = 0, CLICKFOCUS }; + enum TabFocusModel { MOUSETABFOCUS = 0, CLICKTABFOCUS }; enum FollowModel { ///< a window becomes active / focussed on a different workspace IGNORE_OTHER_WORKSPACES = 0, ///< who cares? FOLLOW_ACTIVE_WINDOW, ///< go to that workspace@@ -106,24 +107,24 @@ ~BScreen();
void initWindows(); void initMenus(); - inline bool isSloppyFocus() const { return (*resource.focus_model == SLOPPYFOCUS); } - inline bool isSemiSloppyFocus() const { return (*resource.focus_model == SEMISLOPPYFOCUS); } - inline bool isRootColormapInstalled() const { return root_colormap_installed; } - inline bool isScreenManaged() const { return managed; } - inline bool isSloppyWindowGrouping() const { return *resource.sloppy_window_grouping; } - inline bool isWorkspaceWarping() const { return *resource.workspace_warping; } - inline bool isDesktopWheeling() const { return *resource.desktop_wheeling; } - inline bool doAutoRaise() const { return *resource.auto_raise; } - inline bool clickRaises() const { return *resource.click_raises; } - inline bool doOpaqueMove() const { return *resource.opaque_move; } - inline bool doFullMax() const { return *resource.full_max; } - inline bool doFocusNew() const { return *resource.focus_new; } - inline bool doFocusLast() const { return *resource.focus_last; } - inline bool doShowWindowPos() const { return *resource.show_window_pos; } - inline bool antialias() const { return *resource.antialias; } - inline bool decorateTransient() const { return *resource.decorate_transient; } - inline const std::string &windowMenuFilename() const { return *resource.windowmenufile; } - inline FbTk::ImageControl &imageControl() { return *m_image_control.get(); } + bool isMouseFocus() const { return (*resource.focus_model == MOUSEFOCUS); } + bool isMouseTabFocus() const { return (*resource.tabfocus_model == MOUSETABFOCUS); } + bool isRootColormapInstalled() const { return root_colormap_installed; } + bool isScreenManaged() const { return managed; } + bool isSloppyWindowGrouping() const { return *resource.sloppy_window_grouping; } + bool isWorkspaceWarping() const { return *resource.workspace_warping; } + bool isDesktopWheeling() const { return *resource.desktop_wheeling; } + bool doAutoRaise() const { return *resource.auto_raise; } + bool clickRaises() const { return *resource.click_raises; } + bool doOpaqueMove() const { return *resource.opaque_move; } + bool doFullMax() const { return *resource.full_max; } + bool doFocusNew() const { return *resource.focus_new; } + bool doFocusLast() const { return *resource.focus_last; } + bool doShowWindowPos() const { return *resource.show_window_pos; } + bool antialias() const { return *resource.antialias; } + bool decorateTransient() const { return *resource.decorate_transient; } + const std::string &windowMenuFilename() const { return *resource.windowmenufile; } + FbTk::ImageControl &imageControl() { return *m_image_control.get(); } // menus const FbTk::Menu &rootMenu() const { return *m_rootmenu.get(); } FbTk::Menu &rootMenu() { return *m_rootmenu.get(); }@@ -134,8 +135,10 @@ FbTk::Menu &windowMenu() { return *m_windowmenu.get(); }
ExtraMenus &extraWindowMenus() { return m_extramenus; } const ExtraMenus &extraWindowMenus() const { return m_extramenus; } - inline ResizeModel getResizeModel() const { return *resource.resize_model; } - inline FocusModel getFocusModel() const { return *resource.focus_model; } + ResizeModel getResizeModel() const { return *resource.resize_model; } + FocusModel getFocusModel() const { return *resource.focus_model; } + TabFocusModel getTabFocusModel() const { return *resource.tabfocus_model; } + inline FollowModel getFollowModel() const { return *resource.follow_model; } inline Slit *slit() { return m_slit.get(); }@@ -217,38 +220,40 @@ inline int getEdgeSnapThreshold() const { return *resource.edge_snap_threshold; }
inline RowDirection getRowPlacementDirection() const { return *resource.row_direction; } inline ColumnDirection getColPlacementDirection() const { return *resource.col_direction; } - inline void setRootColormapInstalled(bool r) { root_colormap_installed = r; } - inline void saveRootCommand(std::string rootcmd) { *resource.rootcommand = rootcmd; } - inline void saveFocusModel(FocusModel model) { resource.focus_model = model; } - inline void saveWorkspaces(int w) { *resource.workspaces = w; } + void setRootColormapInstalled(bool r) { root_colormap_installed = r; } + void saveRootCommand(std::string rootcmd) { *resource.rootcommand = rootcmd; } + void saveFocusModel(FocusModel model) { resource.focus_model = model; } + void saveTabFocusModel(TabFocusModel model) { resource.tabfocus_model = model; } + + void saveWorkspaces(int w) { *resource.workspaces = w; } void saveMenu(FbTk::Menu &menu) { m_rootmenu_list.push_back(&menu); } - inline FbWinFrameTheme &winFrameTheme() { return *m_windowtheme.get(); } - inline const FbWinFrameTheme &winFrameTheme() const { return *m_windowtheme.get(); } - inline MenuTheme &menuTheme() { return *m_menutheme.get(); } - inline const MenuTheme &menuTheme() const { return *m_menutheme.get(); } - inline const RootTheme &rootTheme() const { return *m_root_theme.get(); } - inline WinButtonTheme &winButtonTheme() { return *m_winbutton_theme.get(); } - inline const WinButtonTheme &winButtonTheme() const { return *m_winbutton_theme.get(); } + FbWinFrameTheme &winFrameTheme() { return *m_windowtheme.get(); } + const FbWinFrameTheme &winFrameTheme() const { return *m_windowtheme.get(); } + MenuTheme &menuTheme() { return *m_menutheme.get(); } + const MenuTheme &menuTheme() const { return *m_menutheme.get(); } + const RootTheme &rootTheme() const { return *m_root_theme.get(); } + WinButtonTheme &winButtonTheme() { return *m_winbutton_theme.get(); } + const WinButtonTheme &winButtonTheme() const { return *m_winbutton_theme.get(); } - inline FbRootWindow &rootWindow() { return m_root_window; } - inline const FbRootWindow &rootWindow() const { return m_root_window; } + FbRootWindow &rootWindow() { return m_root_window; } + const FbRootWindow &rootWindow() const { return m_root_window; } - inline FbTk::MultLayers &layerManager() { return m_layermanager; } - inline const FbTk::MultLayers &layerManager() const { return m_layermanager; } - inline FbTk::ResourceManager &resourceManager() { return m_resource_manager; } - inline const FbTk::ResourceManager &resourceManager() const { return m_resource_manager; } - inline const std::string &name() const { return m_name; } - inline const std::string &altName() const { return m_altname; } - inline bool isShuttingdown() const { return m_shutdown; } + FbTk::MultLayers &layerManager() { return m_layermanager; } + const FbTk::MultLayers &layerManager() const { return m_layermanager; } + FbTk::ResourceManager &resourceManager() { return m_resource_manager; } + const FbTk::ResourceManager &resourceManager() const { return m_resource_manager; } + const std::string &name() const { return m_name; } + const std::string &altName() const { return m_altname; } + bool isShuttingdown() const { return m_shutdown; } int addWorkspace(); int removeLastWorkspace(); // scroll workspaces - inline void nextWorkspace() { nextWorkspace(1); } - inline void prevWorkspace() { prevWorkspace(1); } + void nextWorkspace() { nextWorkspace(1); } + void prevWorkspace() { prevWorkspace(1); } void nextWorkspace(int delta); void prevWorkspace(int delta); void rightWorkspace(int delta);@@ -272,8 +277,8 @@ void sendToWorkspace(unsigned int workspace, FluxboxWindow *win=0,
bool changeworkspace=true); void reassociateWindow(FluxboxWindow *window, unsigned int workspace_id, bool ignore_sticky); - inline void prevFocus() { prevFocus(0); } - inline void nextFocus() { nextFocus(0); } + void prevFocus() { prevFocus(0); } + void nextFocus() { nextFocus(0); } void prevFocus(int options); void nextFocus(int options); void raiseFocus();@@ -303,8 +308,8 @@ /// (and maximized windows?)
void updateSize(); // Xinerama-related functions - inline bool hasXinerama() const { return m_xinerama_avail; } - inline int numHeads() const { return m_xinerama_num_heads; } + bool hasXinerama() const { return m_xinerama_avail; } + int numHeads() const { return m_xinerama_num_heads; } void initXinerama();@@ -447,6 +452,7 @@ FbTk::Resource<std::string> rootcommand;
FbTk::Resource<ResizeModel> resize_model; FbTk::Resource<std::string> windowmenufile; FbTk::Resource<FocusModel> focus_model; + FbTk::Resource<TabFocusModel> tabfocus_model; FbTk::Resource<FollowModel> follow_model; bool ordered_dither; FbTk::Resource<int> workspaces, edge_snap_threshold, focused_alpha,
@@ -176,31 +176,46 @@ template<>
std::string FbTk::Resource<BScreen::FocusModel>:: getString() { switch (m_value) { - case BScreen::SLOPPYFOCUS: - return string("SloppyFocus"); - case BScreen::SEMISLOPPYFOCUS: - return string("SemiSloppyFocus"); - case BScreen::CLICKTOFOCUS: - return string("ClickToFocus"); + case BScreen::MOUSEFOCUS: + return string("MouseFocus"); + case BScreen::CLICKFOCUS: + return string("ClickFocus"); } // default string - return string("ClickToFocus"); + return string("ClickFocus"); } template<> void FbTk::Resource<BScreen::FocusModel>:: setFromString(char const *strval) { - // auto raise options here for backwards read compatibility - // they are not supported for saving purposes. Nor does the "AutoRaise" - // part actually do anything - if (strcasecmp(strval, "SloppyFocus") == 0 - || strcasecmp(strval, "AutoRaiseSloppyFocus") == 0) - m_value = BScreen::SLOPPYFOCUS; - else if (strcasecmp(strval, "SemiSloppyFocus") == 0 - || strcasecmp(strval, "AutoRaiseSemiSloppyFocus") == 0) - m_value = BScreen::SEMISLOPPYFOCUS; + if (strcasecmp(strval, "MouseFocus") == 0) + m_value = BScreen::MOUSEFOCUS; else if (strcasecmp(strval, "ClickToFocus") == 0) - m_value = BScreen::CLICKTOFOCUS; + m_value = BScreen::CLICKFOCUS; + else + setDefaultValue(); +} + +template<> +std::string FbTk::Resource<BScreen::TabFocusModel>:: +getString() { + switch (m_value) { + case BScreen::MOUSETABFOCUS: + return string("SloppyTabFocus"); + case BScreen::CLICKTABFOCUS: + return string("ClickToTabFocus"); + } + // default string + return string("ClickToTabFocus"); +} + +template<> +void FbTk::Resource<BScreen::TabFocusModel>:: +setFromString(char const *strval) { + if (strcasecmp(strval, "SloppyTabFocus") == 0 ) + m_value = BScreen::MOUSETABFOCUS; + else if (strcasecmp(strval, "ClickToTabFocus") == 0) + m_value = BScreen::CLICKTABFOCUS; else setDefaultValue(); }
@@ -1070,7 +1070,7 @@
if (setinput && setInputFocus()) { return true; } - + return false; }@@ -2033,7 +2033,7 @@
if (focus != frame().focused()) frame().setFocus(focus); - if ((screen().isSloppyFocus() || screen().isSemiSloppyFocus()) + if ((screen().isMouseFocus()) && screen().doAutoRaise()) { if (focused) m_timer.start();@@ -2637,7 +2637,7 @@ // check frame events first
frame().buttonPressEvent(be); if (be.button == 1 || (be.button == 3 && be.state == Mod1Mask)) { - if ((! focused) && (! screen().isSloppyFocus())) { //check focus + if ((! focused) && (! screen().isMouseFocus())) { //check focus setInputFocus(); }@@ -2916,8 +2916,7 @@ return;
} WinClient *client = 0; - // don't waste our time scanning if we aren't real sloppy focus - if (screen().isSloppyFocus()) { + if (screen().isMouseTabFocus()) { // determine if we're in a label button (tab) Client2ButtonMap::iterator it = find_if(m_labelbuttons.begin(),@@ -2929,13 +2928,12 @@ if (it != m_labelbuttons.end())
client = (*it).first; } + if (ev.window == frame().window() || ev.window == m_client->window() || client) { - if ((screen().isSloppyFocus() || screen().isSemiSloppyFocus()) - && !isFocused() || - // or, we are focused, but it isn't the one we want - client && screen().isSloppyFocus() && (m_client != client)) { + + if (screen().isMouseFocus() && !isFocused()) { // check that there aren't any subsequent leave notify events in the // X event queue@@ -2945,16 +2943,16 @@ sa.w = ev.window;
sa.enter = sa.leave = False; XCheckIfEvent(display, &dummy, queueScanner, (char *) &sa); - // if client is set, use setCurrent client, otherwise just setInputFocus if ((!sa.leave || sa.inferior)) { - if (client) - setCurrentClient(*client, true); - else - setInputFocus(); + setInputFocus(); } + } + } - } + if (screen().isMouseTabFocus() && client && client != m_client) { + setCurrentClient(*client, isFocused()); } + } void FluxboxWindow::leaveNotifyEvent(XCrossingEvent &ev) {
@@ -1892,12 +1892,11 @@ 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.getFocusModel()) { - case BScreen::SLOPPYFOCUS: - case BScreen::SEMISLOPPYFOCUS: + case BScreen::MOUSEFOCUS: XSetInputFocus(FbTk::App::instance()->display(), PointerRoot, None, CurrentTime); break; - case BScreen::CLICKTOFOCUS: + case BScreen::CLICKFOCUS: screen.rootWindow().setInputFocus(RevertToPointerRoot, CurrentTime); break; }