From 863eca5517b4f91e26d889d598f41816acf60a40 Mon Sep 17 00:00:00 2001 From: markt Date: Sun, 8 Apr 2007 17:57:49 +0000 Subject: added OnToolbar modifier, removed followModel, fixed unpressed button rendering --- ChangeLog | 10 ++++ data/init.in | 2 +- doc/asciidoc/fluxbox.txt | 38 +++----------- src/ClientMenu.cc | 22 ++------ src/Ewmh.cc | 26 +--------- src/FbTk/Button.cc | 4 +- src/IconbarTool.cc | 113 ++++------------------------------------- src/IconbarTool.hh | 10 +--- src/Keys.cc | 110 +++++++++++++++++++++++++-------------- src/Keys.hh | 32 +++++++----- src/Screen.cc | 15 ++++-- src/Screen.hh | 8 +-- src/ToolFactory.cc | 3 +- src/Toolbar.cc | 28 ++++------ src/Toolbar.hh | 1 - src/Window.cc | 46 ++++++++++++----- src/fluxbox.cc | 11 ++-- util/fluxbox-update_configs.cc | 36 +++++++++++++ 18 files changed, 225 insertions(+), 290 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ad2e61..d77590b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ (Format: Year/Month/Day) Changes for 1.1: +*07/04/08: + * Added OnToolbar modifier to keys file (Mark) + Keys.cc/hh Toolbar.cc/hh Screen.cc/hh IconbarTool.cc fluxbox.cc + * Menu when clicking workspacename in toolbar wasn't getting focused (Mark) + ToolFactory.cc + * Removed followModel, since userFollowModel covers almost all cases (Mark) + IconbarTool.cc ClientMenu.cc Screen.cc/hh Ewmh.cc Window.cc + * Buttons with different textures when pressed weren't getting reset + properly (Mark) + FbTk/Button.cc *07/04/06: * More changes to theme handling (Mark) - introduced window.label.(un)focused.{justify,border{Color,Width}}, diff --git a/data/init.in b/data/init.in index 76b4e08..2dfbc5b 100644 --- a/data/init.in +++ b/data/init.in @@ -33,4 +33,4 @@ session.colorsPerChannel: 4 session.doubleClickInterval: 250 session.cacheMax: 200 session.imageDither: True -session.configVersion: 1 +session.configVersion: 3 diff --git a/doc/asciidoc/fluxbox.txt b/doc/asciidoc/fluxbox.txt index 657e09c..9feb7bc 100644 --- a/doc/asciidoc/fluxbox.txt +++ b/doc/asciidoc/fluxbox.txt @@ -304,10 +304,6 @@ from the init file, but this is an easier and faster way for most users. - *Windows Warping*: If enabled, you can drag windows from one workspace to another. -- *Desktop MouseWheel Switching*: - You will be able to change the workspace with your mousewheel if used on - the desktop or over the toolbar if the option is enabled. - - *Decorate Transient Windows*: With this option enabled all temporary windows will have a border and grips. @@ -558,13 +554,11 @@ The possible tools are: - *PrevWorkspace*: This displays an arrow that allows to switch to the workspace left of the - current one. Same as MouseWheelDown with "Desktop MouseWheel Switching" - enabled. + current one. - *NextWorkspace*: This displays an arrow that allows to switch to the workspace right of the - current one. Same as MouseWheelUp with "Desktop MouseWheel Switching" - enabled. + current one. - *PrevWindow*: This displays an arrow that switches focus to the previous visible window on @@ -712,21 +706,15 @@ session.screen0.toolbar.autoHide: used actively by the user, or they remain visible at all times. Default: False -session.screen0.desktopwheeling: -session.screen0.toolbar.wheeling: - These set the ability to utilize the user's scroll wheel to change the - current workspace. Default: True - session.screen0.windowScrollAction: shade|nexttab This allows you to execute a command by scrolling on the titlebar of a window. For `shade', scrolling down will shade the window, and scrolling up will unshade it. For `nexttab', scrolling down will focus the next tab, and scrolling up will focus the previous one. Default: -session.screen0.reversewheeling: session.screen0.windowScrollReverse: - These switch the roles of scrolling up and scrolling down for the previous - two sets of resources. Default: False + This switches the role of scrolling up and scrolling down for the previous + resource. Default: False session.screen0.slit.layer: session.screen0.toolbar.layer: @@ -809,12 +797,6 @@ session.screen0.iconbar.iconTextPadding: This specifies the space between the window title and the edge of the button. Default: 10 -session.screen0.iconbar.wheelMode: Screen|On|Off - This defines the behavior for scrolling on the iconbar. `Screen' uses the - value set in session.screen0.desktopWheeling . `On' means scrolling on the - iconbar will change the current workspace. `Off' means scrolling on the - iconbar will do nothing. Default: Screen - session.screen0.iconbar.alignment: This value should be changed in the Iconbar Mode menu. Default: Relative @@ -854,16 +836,12 @@ session.screen0.tab.placement: session.screen0.tab.width: This specifies the width of external tabs in pixels. Default: 64 -session.screen0.followModel: session.screen0.userFollowModel: This specifies the behavior when a window on another workspace becomes the - active window. The former is used when an application asks to focus the - window, and the latter is used when the window is activated due to user - actions, such as clicking in the iconbar, menu, or a pager. `Ignore' does - nothing. `Follow' moves to the window's workspace. `Current' moves the - window to the current workspace. `SemiFollow' acts like `Current' for - iconified windows and like `Follow' otherwise. Defaults: Ignore and - Follow, respectively. + active window. `Ignore' does nothing. `Follow' moves to the window's + workspace. `Current' moves the window to the current workspace. + `SemiFollow' acts like `Current' for minimized windows and like `Follow' + otherwise. Default: Follow session.screen0.resizeMode: Bottom|Quadrant|Center Setting this resource to `Quadrant' makes resizing by using the modkey diff --git a/src/ClientMenu.cc b/src/ClientMenu.cc index 08acd40..1bb3ad1 100644 --- a/src/ClientMenu.cc +++ b/src/ClientMenu.cc @@ -40,27 +40,11 @@ public: ~ClientMenuItem() { m_client.titleSig().detach(menu()); } void click(int button, int time) { - if (m_client.fbwindow() == 0) + FluxboxWindow *fbwin = m_client.fbwindow(); + if (fbwin == 0) return; - FluxboxWindow &win = *m_client.fbwindow(); - - if (win.screen().currentWorkspaceID() != win.workspaceNumber() && - !win.isStuck()) { - win.menu().hide(); - BScreen::FollowModel model = win.screen().getUserFollowModel(); - if (model == BScreen::IGNORE_OTHER_WORKSPACES) - return; - // fetch the window to the current workspace - else if ((button == 3) ^ (model == BScreen::FETCH_ACTIVE_WINDOW || - win.isIconic() && model == BScreen::SEMIFOLLOW_ACTIVE_WINDOW)) { - win.screen().sendToWorkspace(win.screen().currentWorkspaceID(), &win, true); - return; - } - // warp to the workspace of the window - win.screen().changeWorkspaceID(win.workspaceNumber()); - } m_client.focus(); - win.raise(); + fbwin->raise(); } const std::string &label() const { return m_client.title(); } diff --git a/src/Ewmh.cc b/src/Ewmh.cc index ea73807..019751f 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc @@ -783,31 +783,9 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, // ce.window = window to focus if (winclient->fbwindow()) { - - FluxboxWindow* fbwin = winclient->fbwindow(); - - // if the raised window is on a different workspace - // we do what the user wish: - // either ignore|go to that workspace|get the window - if (fbwin->screen().currentWorkspaceID() != fbwin->workspaceNumber() - && !fbwin->isStuck()) { - BScreen::FollowModel model = (ce.data.l[0] == 2) ? - fbwin->screen().getUserFollowModel() : - fbwin->screen().getFollowModel(); - if (model == BScreen::FOLLOW_ACTIVE_WINDOW) { - fbwin->screen().changeWorkspaceID(fbwin->workspaceNumber()); - } else if (model == BScreen::FETCH_ACTIVE_WINDOW) { - fbwin->screen().sendToWorkspace(fbwin->screen().currentWorkspaceID(), fbwin); - } else if (model == BScreen::SEMIFOLLOW_ACTIVE_WINDOW) { - if (fbwin->isIconic()) - fbwin->screen().sendToWorkspace(fbwin->screen().currentWorkspaceID(), fbwin); - else - fbwin->screen().changeWorkspaceID(fbwin->workspaceNumber()); - } // else we ignore it. my favourite mode :) - } - fbwin->raise(); + winclient->focus(); + winclient->fbwindow()->raise(); } - winclient->focus(); return true; } else if (ce.message_type == m_net_close_window) { if (winclient == 0) diff --git a/src/FbTk/Button.cc b/src/FbTk/Button.cc index f13adf3..a9b27b2 100644 --- a/src/FbTk/Button.cc +++ b/src/FbTk/Button.cc @@ -129,11 +129,11 @@ void Button::buttonReleaseEvent(XButtonEvent &event) { if (!been_deleted) { mark_if_deleted = 0; if (m_background_pm) { - if (m_pressed_pm != 0) { + if (m_pressed_pm != 0 || m_pressed_color.isAllocated()) { update = true; setBackgroundPixmap(m_background_pm); } - } else if (m_pressed_color.isAllocated()) { + } else if (m_pressed_pm != 0 || m_pressed_color.isAllocated()) { update = true; setBackgroundColor(m_background_color); } diff --git a/src/IconbarTool.cc b/src/IconbarTool.cc index 2c73dc5..df7990d 100644 --- a/src/IconbarTool.cc +++ b/src/IconbarTool.cc @@ -83,40 +83,6 @@ void FbTk::Resource::setFromString(const char *strval) { } template<> -void FbTk::Resource::setDefaultValue() { - m_value = IconbarTool::SCREEN; -} - - -template<> -void FbTk::Resource::setFromString(const char* strval) { - if (strncasecmp(strval, "off", strlen("off")) == 0) - m_value = IconbarTool::OFF; - else if (strncasecmp(strval, "on", strlen("on")) == 0) - m_value = IconbarTool::ON; - else if (strncasecmp(strval, "screen", strlen("screen")) == 0) - m_value = IconbarTool::SCREEN; - else - setDefaultValue(); -} - - -template<> -string FbTk::Resource::getString() const { - switch(m_value) { - case IconbarTool::ON: - return string("On"); - break; - case IconbarTool::SCREEN: - return string("Screen"); - break; - case IconbarTool::OFF: - default: - return string("Off"); - }; -} - -template<> void FbTk::Resource::setDefaultValue() { m_value = Container::RELATIVE; } @@ -330,67 +296,23 @@ private: class FocusCommand: public FbTk::Command { public: - explicit FocusCommand(const IconbarTool& tool, FluxboxWindow &win) : - m_win(win), m_tool(tool) { } + explicit FocusCommand(Focusable &win): m_win(win) { } void execute() { // this needs to be a local variable, as this object could be destroyed // if the workspace is changed. - FluxboxWindow &win = m_win; - if(win.isIconic() || !win.isFocused()) { - switch(win.screen().getUserFollowModel()) { - case BScreen::SEMIFOLLOW_ACTIVE_WINDOW: - if (win.isIconic()) { - win.screen().sendToWorkspace(win.screen().currentWorkspaceID(), &win); - } else { - win.screen().changeWorkspaceID(win.workspaceNumber()); - } - break; - case BScreen::FETCH_ACTIVE_WINDOW: - win.screen().sendToWorkspace(win.screen().currentWorkspaceID(), &win); - break; - case BScreen::FOLLOW_ACTIVE_WINDOW: - if (!win.isStuck()) - win.screen().changeWorkspaceID(win.workspaceNumber()); - default: - break; - }; - win.raiseAndFocus(); - } else - win.iconify(); - } - -private: - FluxboxWindow &m_win; - const IconbarTool& m_tool; -}; - -// simple forwarding of wheeling, but only -// if desktopwheeling is enabled -class WheelWorkspaceCmd : public FbTk::Command { -public: - explicit WheelWorkspaceCmd(const IconbarTool& tool, Focusable &win, - const char* cmd) : - m_win(win), m_cmd(CommandParser::instance().parseLine(cmd)), m_tool(tool) { } - void execute() { - - switch(m_tool.wheelMode()) { - case IconbarTool::ON: - m_cmd->execute(); - break; - case IconbarTool::SCREEN: - if(m_win.screen().isDesktopWheeling()) - m_cmd->execute(); - break; - case IconbarTool::OFF: - default: - break; - }; + FluxboxWindow *fbwin = m_win.fbwindow(); + if (!fbwin) + return; + if (m_win.isFocused()) + fbwin->iconify(); + else { + m_win.focus(); + fbwin->raise(); + } } private: Focusable &m_win; - RefCmd m_cmd; - const IconbarTool& m_tool; }; }; // end anonymous namespace @@ -404,9 +326,6 @@ IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme, BScr m_empty_pm( screen.imageControl() ), m_rc_mode(screen.resourceManager(), WORKSPACE, screen.name() + ".iconbar.mode", screen.altName() + ".Iconbar.Mode"), - m_wheel_mode(screen.resourceManager(), OFF, - screen.name() + ".iconbar.wheelMode", - screen.name() + ".iconbar.WheelMode"), m_rc_alignment(screen.resourceManager(), Container::LEFT, screen.name() + ".iconbar.alignment", screen.altName() + ".Iconbar.Alignment"), m_rc_client_width(screen.resourceManager(), 70, @@ -730,20 +649,10 @@ void IconbarTool::addWindow(Focusable &win) { #endif // DEBUG IconButton *button = new IconButton(m_icon_container, m_theme, win); - RefCmd next_workspace(new ::WheelWorkspaceCmd(*this, win, "nextworkspace")); - RefCmd prev_workspace(new ::WheelWorkspaceCmd(*this, win, "prevworkspace")); - - RefCmd focus_cmd(new ::FocusCommand(*this, *fbwin)); + RefCmd focus_cmd(new ::FocusCommand(win)); RefCmd menu_cmd(new ::ShowMenu(*fbwin)); button->setOnClick(focus_cmd, 1); button->setOnClick(menu_cmd, 3); - if(win.screen().isReverseWheeling()) { - button->setOnClick(next_workspace, 5); - button->setOnClick(prev_workspace, 4); - } else { - button->setOnClick(next_workspace, 4); - button->setOnClick(prev_workspace, 5); - } renderButton(*button, false); // update the attributes, but don't clear it m_icon_container.insertItem(button); diff --git a/src/IconbarTool.hh b/src/IconbarTool.hh index afa2182..323c714 100644 --- a/src/IconbarTool.hh +++ b/src/IconbarTool.hh @@ -57,13 +57,6 @@ public: ALLWINDOWS ///< all windows and all icons from all workspaces }; - /// wheeling on iconbutton - enum WheelMode { - OFF, ///< no wheeling, default mode - ON, ///< enabled wheeling - SCREEN ///< in perfect harmony with desktopwheeling-value - }; - IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme, BScreen &screen, FbTk::Menu &menu); ~IconbarTool(); @@ -85,11 +78,11 @@ public: unsigned int borderWidth() const; Mode mode() const { return *m_rc_mode; } - WheelMode wheelMode() const { return *m_wheel_mode; } void setOrientation(FbTk::Orientation orient); Container::Alignment alignment() const { return m_icon_container.alignment(); } + const BScreen &screen() const { return m_screen; } private: /// @return button associated with window @@ -123,7 +116,6 @@ private: IconList m_icon_list; FbTk::Resource m_rc_mode; - FbTk::Resource m_wheel_mode; FbTk::Resource m_rc_alignment; ///< alignment of buttons FbTk::Resource m_rc_client_width; ///< size of client button in LEFT/RIGHT mode FbTk::Resource m_rc_client_padding; ///< padding of the text diff --git a/src/Keys.cc b/src/Keys.cc index 97a83bf..aca7428 100644 --- a/src/Keys.cc +++ b/src/Keys.cc @@ -99,18 +99,7 @@ using std::vector; using std::ifstream; using std::pair; -Keys::Keys(): - m_display(FbTk::App::instance()->display()) -{ - typedef std::list ScreenList; - ScreenList screen_list = Fluxbox::instance()->screenList(); - ScreenList::iterator it = screen_list.begin(); - ScreenList::iterator it_end = screen_list.end(); - - for (; it != it_end; ++it) - m_window_list.push_back(RootWindow(m_display,(*it)->screenNumber())); - -} +Keys::Keys(): m_display(FbTk::App::instance()->display()) { } Keys::~Keys() { ungrabKeys(); @@ -125,37 +114,69 @@ void Keys::deleteTree() { m_map.clear(); } +// keys are only grabbed in global context void Keys::grabKey(unsigned int key, unsigned int mod) { - std::list::iterator it = m_window_list.begin(); - std::list::iterator it_end = m_window_list.end(); + WindowMap::iterator it = m_window_map.begin(); + WindowMap::iterator it_end = m_window_map.end(); - for (; it != it_end; ++it) - FbTk::KeyUtil::grabKey(key, mod, *it); + for (; it != it_end; ++it) { + if ((it->second & Keys::GLOBAL) > 0) + FbTk::KeyUtil::grabKey(key, mod, it->first); + } } +// keys are only grabbed in global context void Keys::ungrabKeys() { - std::list::iterator it = m_window_list.begin(); - std::list::iterator it_end = m_window_list.end(); + WindowMap::iterator it = m_window_map.begin(); + WindowMap::iterator it_end = m_window_map.end(); - for (; it != it_end; ++it) - FbTk::KeyUtil::ungrabKeys(*it); + for (; it != it_end; ++it) { + if ((it->second & Keys::GLOBAL) > 0) + FbTk::KeyUtil::ungrabKeys(it->first); + } } -void Keys::grabButton(unsigned int button, unsigned int mod) { - std::list::iterator it = m_window_list.begin(); - std::list::iterator it_end = m_window_list.end(); +// ON_DESKTOP context doesn't need to be grabbed +void Keys::grabButton(unsigned int button, unsigned int mod, int context) { + WindowMap::iterator it = m_window_map.begin(); + WindowMap::iterator it_end = m_window_map.end(); - for (; it != it_end; ++it) - FbTk::KeyUtil::grabButton(button, mod, *it, - ButtonPressMask|ButtonReleaseMask); + for (; it != it_end; ++it) { + if ((context & it->second & ~Keys::ON_DESKTOP) > 0) + FbTk::KeyUtil::grabButton(button, mod, it->first, + ButtonPressMask|ButtonReleaseMask); + } } void Keys::ungrabButtons() { - std::list::iterator it = m_window_list.begin(); - std::list::iterator it_end = m_window_list.end(); + WindowMap::iterator it = m_window_map.begin(); + WindowMap::iterator it_end = m_window_map.end(); for (; it != it_end; ++it) - FbTk::KeyUtil::ungrabButtons(*it); + FbTk::KeyUtil::ungrabButtons(it->first); +} + +void Keys::grabWindow(Window win) { + if (!m_keylist) + return; + + // make sure the window is in our list + WindowMap::iterator win_it = m_window_map.find(win); + if (win_it == m_window_map.end()) + return; + + keylist_t::iterator it = m_keylist->keylist.begin(); + keylist_t::iterator it_end = m_keylist->keylist.end(); + for (; it != it_end; ++it) { + // keys are only grabbed in global context + if ((win_it->second & Keys::GLOBAL) > 0 && (*it)->type == KeyPress) + FbTk::KeyUtil::grabKey((*it)->key, (*it)->mod, win); + // ON_DESKTOP buttons don't need to be grabbed + else if ((win_it->second & (*it)->context & ~Keys::ON_DESKTOP) > 0 && + (*it)->type == ButtonPress) + FbTk::KeyUtil::grabButton((*it)->key, (*it)->mod, win, + ButtonPressMask|ButtonReleaseMask); + } } /** @@ -251,6 +272,8 @@ bool Keys::addBinding(const string &linebuffer) { mod |= tmpmod; //If it's a modifier else if (strcasecmp("ondesktop", val[argc].c_str()) == 0) context |= ON_DESKTOP; + else if (strcasecmp("ontoolbar", val[argc].c_str()) == 0) + context |= ON_TOOLBAR; else if (strcasecmp("NONE",val[argc].c_str())) { // check if it's a mouse button if (!strcasecmp(val[argc].substr(0,5).c_str(), "mouse") && @@ -322,16 +345,15 @@ bool Keys::addBinding(const string &linebuffer) { } // return true if bound to a command, else false -bool Keys::doAction(int type, unsigned int mods, unsigned int key) { +bool Keys::doAction(int type, unsigned int mods, unsigned int key, + int context) { static t_key* next_key = m_keylist; if (!next_key) next_key = m_keylist; mods = FbTk::KeyUtil::instance().cleanMods(mods); - // at the moment, any key/button that gets here is on root window - // context will need to be added as an argument to doAction, though - t_key *temp_key = next_key->find(type, mods, key, ON_DESKTOP|GLOBAL); + t_key *temp_key = next_key->find(type, mods, key, context); // need to save this for emacs-style keybindings static t_key *saved_keymode = 0; @@ -369,6 +391,19 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key) { return true; } +/// adds the window to m_window_map, so we know to grab buttons on it +void Keys::registerWindow(Window win, int context) { + m_window_map[win] = context; + grabWindow(win); +} + +/// remove the window from the window map, probably being deleted +void Keys::unregisterWindow(Window win) { + FbTk::KeyUtil::ungrabKeys(win); + FbTk::KeyUtil::ungrabButtons(win); + m_window_map.erase(win); +} + /** deletes the tree and load configuration returns true on success else false @@ -392,14 +427,13 @@ void Keys::setKeyMode(t_key *keyMode) { keylist_t::iterator it_end = keyMode->keylist.end(); for (; it != it_end; ++it) { if ((*it)->type == KeyPress) - grabKey((*it)->key,(*it)->mod); - else if ((*it)->context == GLOBAL) - grabButton((*it)->key,(*it)->mod); - // we must use root window's event mask to get ON_DESKTOP events + grabKey((*it)->key, (*it)->mod); + else + grabButton((*it)->key, (*it)->mod, (*it)->context); } m_keylist = keyMode; } - + Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, int context_, FbTk::RefCount command) { key = key_; diff --git a/src/Keys.hh b/src/Keys.hh index c075d38..2d022c6 100644 --- a/src/Keys.hh +++ b/src/Keys.hh @@ -25,7 +25,6 @@ #define KEYS_HH #include -#include #include #include #include @@ -53,11 +52,7 @@ public: // and so on... }; - /** - Constructor - @param display display connection - @param filename file to load, default none - */ + /// constructor explicit Keys(); /// destructor ~Keys(); @@ -80,7 +75,12 @@ public: /** do action from XKeyEvent; return false if not bound to anything */ - bool doAction(int type, unsigned int mods, unsigned int key); + bool doAction(int type, unsigned int mods, unsigned int key, int context); + + /// register a window so that proper keys/buttons get grabbed on it + void registerWindow(Window win, int context); + /// unregister window + void unregisterWindow(Window win); /** Reload configuration from filename @@ -94,13 +94,14 @@ private: void grabKey(unsigned int key, unsigned int mod); void ungrabKeys(); - void grabButton(unsigned int button, unsigned int mod); + void grabButton(unsigned int button, unsigned int mod, int context); void ungrabButtons(); + void grabWindow(Window win); std::string m_filename; class t_key; - typedef std::vector keylist_t; + typedef std::list keylist_t; class t_key { public: @@ -113,11 +114,12 @@ private: int context_) { // t_key ctor sets context_ of 0 to GLOBAL, so we must here too context_ = context_ ? context_ : GLOBAL; - for (size_t i = 0; i < keylist.size(); i++) { - if (keylist[i]->type == type_ && keylist[i]->key == key_ && - (keylist[i]->context & context_) > 0 && keylist[i]->mod == + keylist_t::iterator it = keylist.begin(), it_end = keylist.end(); + for (; it != it_end; it++) { + if ((*it)->type == type_ && (*it)->key == key_ && + ((*it)->context & context_) > 0 && (*it)->mod == FbTk::KeyUtil::instance().isolateModifierMask(mod_)) - return keylist[i]; + return *it; } return 0; } @@ -138,7 +140,9 @@ private: keyspace_t m_map; Display *m_display; ///< display connection - std::list m_window_list; + + typedef std::map WindowMap; + WindowMap m_window_map; }; #endif // KEYS_HH diff --git a/src/Screen.cc b/src/Screen.cc index 066171b..d433907 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -287,8 +287,6 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm, opaque_move(rm, false, scrname + ".opaqueMove", altscrname+".OpaqueMove"), full_max(rm, false, scrname+".fullMaximization", altscrname+".FullMaximization"), workspace_warping(rm, true, scrname+".workspacewarping", altscrname+".WorkspaceWarping"), - desktop_wheeling(rm, true, scrname+".desktopwheeling", altscrname+".DesktopWheeling"), - reverse_wheeling(rm, false, scrname+".reversewheeling", altscrname+".ReverseWheeling"), show_window_pos(rm, true, scrname+".showwindowposition", altscrname+".ShowWindowPosition"), auto_raise(rm, true, scrname+".autoRaise", altscrname+".AutoRaise"), click_raises(rm, true, scrname+".clickRaises", altscrname+".ClickRaises"), @@ -298,7 +296,6 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm, resize_model(rm, BOTTOMRESIZE, scrname+".resizeMode", altscrname+".ResizeMode"), tab_placement(rm, FbWinFrame::TOPLEFT, scrname+".tab.placement", altscrname+".Tab.Placement"), windowmenufile(rm, "", scrname+".windowMenu", altscrname+".WindowMenu"), - follow_model(rm, IGNORE_OTHER_WORKSPACES, scrname+".followModel", altscrname+".followModel"), user_follow_model(rm, FOLLOW_ACTIVE_WINDOW, scrname+".userFollowModel", altscrname+".UserFollowModel"), workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"), edge_snap_threshold(rm, 0, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"), @@ -422,6 +419,10 @@ BScreen::BScreen(FbTk::ResourceManager &rm, FbTk::EventManager *evm = FbTk::EventManager::instance(); evm->add(*this, rootWindow()); + Keys *keys = Fluxbox::instance()->keys(); + if (keys) + keys->registerWindow(rootWindow().window(), + Keys::GLOBAL|Keys::ON_DESKTOP); rootWindow().setCursor(XCreateFontCursor(disp, XC_left_ptr)); // load this screens resources @@ -546,6 +547,9 @@ BScreen::~BScreen() { FbTk::EventManager *evm = FbTk::EventManager::instance(); evm->remove(rootWindow()); + Keys *keys = Fluxbox::instance()->keys(); + if (keys) + keys->unregisterWindow(rootWindow().window()); if (m_rootmenu.get() != 0) m_rootmenu->removeAll(); @@ -785,7 +789,8 @@ void BScreen::update(FbTk::Subject *subj) { void BScreen::keyPressEvent(XKeyEvent &ke) { if (!m_typing_ahead) { - Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode); + Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode, + Keys::GLOBAL|Keys::ON_DESKTOP); return; } @@ -839,7 +844,7 @@ void BScreen::buttonPressEvent(XButtonEvent &be) { imageControl().installRootColormap(); Keys *keys = Fluxbox::instance()->keys(); - keys->doAction(be.type, be.state, be.button); + keys->doAction(be.type, be.state, be.button, Keys::GLOBAL|Keys::ON_DESKTOP); } void BScreen::notifyUngrabKeyboard() { diff --git a/src/Screen.hh b/src/Screen.hh index f3096c1..0354b99 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -119,8 +119,6 @@ public: bool isRootColormapInstalled() const { return root_colormap_installed; } bool isScreenManaged() const { return managed; } bool isWorkspaceWarping() const { return *resource.workspace_warping; } - bool isDesktopWheeling() const { return *resource.desktop_wheeling; } - bool isReverseWheeling() const { return *resource.reverse_wheeling; } bool doAutoRaise() const { return *resource.auto_raise; } bool clickRaises() const { return *resource.click_raises; } bool doOpaqueMove() const { return *resource.opaque_move; } @@ -144,7 +142,6 @@ public: ResizeModel getResizeModel() const { return *resource.resize_model; } - inline FollowModel getFollowModel() const { return *resource.follow_model; } inline FollowModel getUserFollowModel() const { return *resource.user_follow_model; } inline const std::string &getScrollAction() const { return *resource.scroll_action; } @@ -562,15 +559,14 @@ private: const std::string &altscrname); FbTk::Resource image_dither, opaque_move, full_max, - workspace_warping, - desktop_wheeling, reverse_wheeling, show_window_pos, + workspace_warping, show_window_pos, auto_raise, click_raises, decorate_transient; FbTk::Resource default_deco; FbTk::Resource rootcommand; FbTk::Resource resize_model; FbTk::Resource tab_placement; FbTk::Resource windowmenufile; - FbTk::Resource follow_model, user_follow_model; + FbTk::Resource user_follow_model; bool ordered_dither; FbTk::Resource workspaces, edge_snap_threshold, focused_alpha, unfocused_alpha, menu_alpha, menu_delay, menu_delay_close, tab_width; diff --git a/src/ToolFactory.cc b/src/ToolFactory.cc index f2d1ccd..ee1316a 100644 --- a/src/ToolFactory.cc +++ b/src/ToolFactory.cc @@ -65,7 +65,8 @@ public: m_tbar.screen().getHeadWidth(head), m_tbar.screen().getHeadHeight(head)); m_tbar.menu().move(m.first, m.second); - m_tbar.menu().show(); + m_tbar.menu().show(); + m_tbar.menu().grabInputFocus(); } private: Toolbar &m_tbar; diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 1305279..a1906c0 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -33,6 +33,7 @@ #include "ToolbarTheme.hh" #include "fluxbox.hh" +#include "Keys.hh" #include "Screen.hh" #include "IntResMenuItem.hh" #include "BoolMenuItem.hh" @@ -279,6 +280,8 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, size_t width): scrn.resourceManager().unlock(); // setup to listen to child events FbTk::EventManager::instance()->addParent(*this, window()); + Fluxbox::instance()->keys()->registerWindow(window().window(), + Keys::ON_TOOLBAR); // get everything together reconfigure(); // this gets done by the screen later as it loads @@ -286,6 +289,7 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, size_t width): } Toolbar::~Toolbar() { + Fluxbox::instance()->keys()->unregisterWindow(window().window()); FbTk::EventManager::instance()->remove(window()); // remove menu items before we delete tools so we dont end up // with dangling pointers to old submenu items (internal menus) @@ -512,6 +516,11 @@ void Toolbar::reconfigure() { void Toolbar::buttonPressEvent(XButtonEvent &be) { + if (Fluxbox::instance()->keys()->doAction(be.type, be.state, be.button, + Keys::ON_TOOLBAR)) + return; + if (be.button == 1) + raise(); if (be.button != 3) return; @@ -539,25 +548,6 @@ void Toolbar::buttonPressEvent(XButtonEvent &be) { } - -void Toolbar::buttonReleaseEvent(XButtonEvent &re) { - if (re.button == 1) { - raise(); - } else if (re.button == 4) { //mousewheel scroll up - if(screen().isReverseWheeling()) { - screen().prevWorkspace(1); - } else { - screen().nextWorkspace(1); - } - } else if (re.button == 5) { //mousewheel scroll down - if(screen().isReverseWheeling()) { - screen().nextWorkspace(1); - } else { - screen().prevWorkspace(1); - } - } -} - void Toolbar::enterNotifyEvent(XCrossingEvent ¬_used) { if (! doAutoHide()) { if (isHidden()) diff --git a/src/Toolbar.hh b/src/Toolbar.hh index 5ac2114..243ce52 100644 --- a/src/Toolbar.hh +++ b/src/Toolbar.hh @@ -88,7 +88,6 @@ public: */ //@{ void buttonPressEvent(XButtonEvent &be); - void buttonReleaseEvent(XButtonEvent &be); void enterNotifyEvent(XCrossingEvent &ce); void leaveNotifyEvent(XCrossingEvent &ce); void exposeEvent(XExposeEvent &ee); diff --git a/src/Window.cc b/src/Window.cc index 2943366..09b048b 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -1309,8 +1309,8 @@ void FluxboxWindow::maxSize(unsigned int &max_width, unsigned int &max_height) { // returns whether the focus was "set" to this window // it doesn't guarantee that it has focus, but says that we have -// tried. A FocusqIn event should eventually arrive for that -// window if it actually got the focus, then setFocusedFlag is called, +// tried. A FocusIn event should eventually arrive for that +// window if it actually got the focus, then setFocusFlag is called, // which updates all the graphics etc bool FluxboxWindow::focus() { @@ -1343,6 +1343,20 @@ bool FluxboxWindow::focus() { if (! m_client->validateClient()) return false; + if (screen().currentWorkspaceID() != workspaceNumber() && !isStuck()) { + menu().hide(); + BScreen::FollowModel model = screen().getUserFollowModel(); + if (model == BScreen::IGNORE_OTHER_WORKSPACES) + return false; + // fetch the window to the current workspace + if (model == BScreen::FETCH_ACTIVE_WINDOW || + (isIconic() && model == BScreen::SEMIFOLLOW_ACTIVE_WINDOW)) + screen().sendToWorkspace(screen().currentWorkspaceID(), this, true); + // warp to the workspace of the window + else + screen().changeWorkspaceID(workspaceNumber()); + } + // this needs to be here rather than setFocusFlag because // FocusControl::revertFocus will return before FocusIn events arrive m_screen.focusControl().setScreenFocusedWindow(*m_client); @@ -2310,6 +2324,22 @@ void FluxboxWindow::mapRequestEvent(XMapRequestEvent &re) { // Note: this function never gets called from WithdrawnState // initial state is handled in restoreAttributes() and init() + + // check what to do if window is on another workspace + if (screen().currentWorkspaceID() != workspaceNumber() && !isStuck()) { + menu().hide(); + BScreen::FollowModel model = screen().getUserFollowModel(); + if (model == BScreen::IGNORE_OTHER_WORKSPACES) + return; + // fetch the window to the current workspace + if (model == BScreen::FETCH_ACTIVE_WINDOW || + (isIconic() && model == BScreen::SEMIFOLLOW_ACTIVE_WINDOW)) + screen().sendToWorkspace(screen().currentWorkspaceID(), this, true); + // warp to the workspace of the window + else + screen().changeWorkspaceID(workspaceNumber()); + } + setCurrentClient(*client, false); // focus handled on MapNotify deiconify(false); @@ -2330,8 +2360,6 @@ void FluxboxWindow::mapNotifyEvent(XMapEvent &ne) { #ifdef DEBUG cerr<<"FluxboxWindow::mapNotify: not override redirect ans visible!"<grab(); if (! client->validateClient()) return; @@ -2345,17 +2373,7 @@ void FluxboxWindow::mapNotifyEvent(XMapEvent &ne) { else if (m_screen.focusControl().focusNew()) Fluxbox::instance()->attentionHandler().addAttention(*client); - iconic = false; - - // Auto-group from tab? - if (!client->isTransient()) { -#ifdef DEBUG - cerr<<__FILE__<<"("<<__FUNCTION__<<") TODO check grouping here"<ungrab(); } } diff --git a/src/fluxbox.cc b/src/fluxbox.cc index af9482d..3f7d9f7 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -330,6 +330,11 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile #endif // HAVE_GETPID + // Create keybindings handler and load keys file + // Note: this needs to be done before creating screens + m_key.reset(new Keys); + m_key->load(StringUtil::expandFilename(*m_rc_keyfile).c_str()); + vector screens; int i; @@ -425,10 +430,6 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile m_reconfigure_wait = m_reread_menu_wait = false; - // Create keybindings handler and load keys file - m_key.reset(new Keys); - m_key->load(StringUtil::expandFilename(*m_rc_keyfile).c_str()); - m_resourcemanager.unlock(); ungrab(); @@ -646,7 +647,7 @@ void Fluxbox::setupConfigFiles() { if (create_init) FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str()); -#define CONFIG_VERSION 1 +#define CONFIG_VERSION 3 FbTk::Resource config_version(m_resourcemanager, 0, "session.configVersion", "Session.ConfigVersion"); if (*config_version < CONFIG_VERSION) { diff --git a/util/fluxbox-update_configs.cc b/util/fluxbox-update_configs.cc index c3b5a85..563bada 100644 --- a/util/fluxbox-update_configs.cc +++ b/util/fluxbox-update_configs.cc @@ -146,6 +146,42 @@ int run_updates(int old_version, FbTk::ResourceManager rm) { new_version = 2; } + if (old_version < 3) { // move toolbar wheeling to keys file + string whole_keyfile = read_file(keyfilename); + string new_keyfile = ""; + // let's put our new keybindings first, so they're easy to find + new_keyfile += "!mouse actions added by fluxbox-update_configs\n"; + bool keep_changes = false; + + // scrolling on toolbar needs to match user's toolbar wheeling settings + FbTk::Resource rc_wheeling(rm, "Off", + "session.screen0.iconbar.wheelMode", + "Session.Screen0.Iconbar.WheelMode"); + FbTk::Resource rc_screen(rm, true, + "session.screen0.desktopwheeling", + "Session.Screen0.DesktopWheeling"); + FbTk::Resource rc_reverse(rm, false, + "session.screen0.reversewheeling", + "Session.Screen0.ReverseWheeling"); + if (strcasecmp((*rc_wheeling).c_str(), "On") == 0 || + (strcasecmp((*rc_wheeling).c_str(), "Screen") && *rc_screen)) { + keep_changes = true; + if (*rc_reverse) { // if you ask me, this should have been default + new_keyfile += "OnToolbar Mouse4 :prevWorkspace\n"; + new_keyfile += "OnToolbar Mouse5 :nextWorkspace\n"; + } else { + new_keyfile += "OnToolbar Mouse4 :nextWorkspace\n"; + new_keyfile += "OnToolbar Mouse5 :prevWorkspace\n"; + } + } + new_keyfile += "\n"; // just for good looks + new_keyfile += whole_keyfile; // don't forget user's old keybindings + + if (keep_changes) + write_file(keyfilename, new_keyfile); + new_version = 3; + } + return new_version; } -- cgit v0.11.2