From 08ebff4b319f51b4263cded0bb9c04103bcd9c3a Mon Sep 17 00:00:00 2001 From: markt Date: Tue, 20 Nov 2007 19:01:45 +0000 Subject: move titlebar click handling to FluxboxWindow, fix buttons getting ungrabbed --- src/FbTk/EventHandler.hh | 1 + src/FbWinFrame.cc | 66 +------------------------- src/FbWinFrame.hh | 14 ------ src/FocusableList.cc | 4 +- src/Keys.cc | 12 ++++- src/Keys.hh | 8 +++- src/Screen.cc | 2 +- src/Toolbar.cc | 2 +- src/Window.cc | 117 ++++++++++++++++++++--------------------------- 9 files changed, 73 insertions(+), 153 deletions(-) diff --git a/src/FbTk/EventHandler.hh b/src/FbTk/EventHandler.hh index 45c7a2a..96ecd79 100644 --- a/src/FbTk/EventHandler.hh +++ b/src/FbTk/EventHandler.hh @@ -59,6 +59,7 @@ public: virtual void enterNotifyEvent(XCrossingEvent &) { } virtual void notifyUngrabKeyboard() { } + virtual void grabButtons() { } }; } // end namespace FbTk diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc index cc7d379..83610ea 100644 --- a/src/FbWinFrame.cc +++ b/src/FbWinFrame.cc @@ -96,7 +96,6 @@ FbWinFrame::FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageContr m_shaded(false), m_focused_alpha(0), m_unfocused_alpha(0), - m_double_click_time(0), m_themelistener(*this), m_shape(m_window, theme.shapePlace()), m_disable_themeshape(false) { @@ -109,23 +108,6 @@ FbWinFrame::~FbWinFrame() { removeAllButtons(); } -bool FbWinFrame::setOnClickTitlebar(FbTk::RefCount &ref, int mousebutton_num, - bool double_click, bool pressed) { - // find mousebutton_num - if (mousebutton_num < 1 || mousebutton_num > 5) - return false; - if (double_click) - m_commands[mousebutton_num - 1].double_click = ref; - else { - if (pressed) - m_commands[mousebutton_num - 1].click_pressed = ref; - else - m_commands[mousebutton_num - 1].click = ref; - } - - return true; -} - bool FbWinFrame::setTabMode(TabMode tabmode) { if (m_tabmode == tabmode) return false; @@ -570,10 +552,6 @@ void FbWinFrame::setUseDefaultAlpha(bool default_alpha) } } -void FbWinFrame::setDoubleClickTime(unsigned int time) { - m_double_click_time = time; -} - void FbWinFrame::addLeftButton(FbTk::Button *btn) { if (btn == 0) // valid button? return; @@ -685,7 +663,7 @@ void FbWinFrame::setClientWindow(FbTk::FbWindow &win) { win.reparent(m_window, 0, clientArea().y()); // remask window so we get events win.setEventMask(PropertyChangeMask | StructureNotifyMask | - FocusChangeMask); + FocusChangeMask | KeyPressMask); m_window.setEventMask(ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | EnterWindowMask | SubstructureRedirectMask); @@ -855,47 +833,6 @@ void FbWinFrame::removeEventHandler() { evm.remove(m_clientarea); } -void FbWinFrame::buttonPressEvent(XButtonEvent &event) { - m_tab_container.tryButtonPressEvent(event); - if (event.window == m_grip_right.window() || - event.window == m_grip_left.window() || - event.window == m_clientarea.window() || - event.window == m_window.window()) - return; - // we handle only buttons 0 to 5 - if (event.button > 5 || event.button < 1) - return; - - if (*m_commands[event.button - 1].click_pressed) - m_commands[event.button - 1].click_pressed->execute(); -} - -void FbWinFrame::buttonReleaseEvent(XButtonEvent &event) { - // we continue even if a button got the event - m_tab_container.tryButtonReleaseEvent(event); - - if (event.window == m_grip_right.window() || - event.window == m_grip_left.window() || - event.window == m_clientarea.window() || - event.window == m_handle.window() || - event.window == m_window.window()) - return; - - if (event.button < 1 || event.button > 5) - return; - - static Time last_release_time = 0; - bool double_click = (event.time - last_release_time <= m_double_click_time); - last_release_time = event.time; - int real_button = event.button - 1; - - if (double_click && *m_commands[real_button].double_click) - m_commands[real_button].double_click->execute(); - else if (*m_commands[real_button].click) - m_commands[real_button].click->execute(); - -} - void FbWinFrame::exposeEvent(XExposeEvent &event) { if (m_titlebar == event.window) { m_titlebar.clearArea(event.x, event.y, event.width, event.height); @@ -1409,7 +1346,6 @@ void FbWinFrame::init() { m_button_pm = m_button_unfocused_pm = m_button_pressed_pm = 0; m_grip_unfocused_pm = m_grip_focused_pm = 0; - m_double_click_time = 200; m_button_size = 26; m_clientarea.setBorderWidth(0); diff --git a/src/FbWinFrame.hh b/src/FbWinFrame.hh index bdc2add..9bd29dd 100644 --- a/src/FbWinFrame.hh +++ b/src/FbWinFrame.hh @@ -88,10 +88,6 @@ public: /// destroy frame ~FbWinFrame(); - /// setup actions for titlebar - bool setOnClickTitlebar(FbTk::RefCount &cmd, int button_num, - bool double_click=false, bool pressed=false); - void hide(); void show(); inline bool isVisible() const { return m_visible; } @@ -124,7 +120,6 @@ public: /// set focus/unfocus style void setFocus(bool newvalue); inline void setFocusTitle(const std::string &str) { m_label.setText(str); } - void setDoubleClickTime(unsigned int time); bool setTabMode(TabMode tabmode); inline void updateTabProperties() { alignTabs(); } @@ -186,8 +181,6 @@ public: @name Event handlers */ //@{ - void buttonPressEvent(XButtonEvent &event); - void buttonReleaseEvent(XButtonEvent &event); void exposeEvent(XExposeEvent &event); void configureNotifyEvent(XConfigureEvent &event); void handleEvent(XEvent &event); @@ -377,13 +370,6 @@ private: bool m_shaded; ///< wheter we're shaded or not unsigned char m_focused_alpha; ///< focused alpha value unsigned char m_unfocused_alpha; ///< unfocused alpha value - unsigned int m_double_click_time; ///< the time period that's considerd to be a double click - struct MouseButtonAction { - FbTk::RefCount click; ///< what to do when we release mouse button - FbTk::RefCount click_pressed; ///< what to do when we press mouse button - FbTk::RefCount double_click; ///< what to do when we double click - }; - MouseButtonAction m_commands[5]; ///< hardcoded to five ... //!! TODO, change this class ThemeListener: public FbTk::Observer { public: diff --git a/src/FocusableList.cc b/src/FocusableList.cc index 8a5c8f7..8c43181 100644 --- a/src/FocusableList.cc +++ b/src/FocusableList.cc @@ -126,11 +126,11 @@ void FocusableList::update(FbTk::Subject *subj) { FocusableListSubject *fsubj = static_cast(subj); if (subj == &m_parent->addSig()) { + attachSignals(*fsubj->win()); if (m_pat->match(*fsubj->win())) { insertFromParent(*fsubj->win()); m_addsig.notify(fsubj->win()); - } else // we still want to watch it, in case it changes to match - attachSignals(*fsubj->win()); + } } else if (subj == &m_parent->removeSig()) remove(*fsubj->win()); else if (subj == &m_parent->resetSig()) diff --git a/src/Keys.cc b/src/Keys.cc index 7e6c93e..2d26ab8 100644 --- a/src/Keys.cc +++ b/src/Keys.cc @@ -168,6 +168,7 @@ void Keys::grabWindow(Window win) { if (win_it == m_window_map.end()) return; + m_handler_map[win]->grabButtons(); keylist_t::iterator it = m_keylist->keylist.begin(); keylist_t::iterator it_end = m_keylist->keylist.end(); for (; it != it_end; ++it) { @@ -428,8 +429,9 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key, } /// adds the window to m_window_map, so we know to grab buttons on it -void Keys::registerWindow(Window win, int context) { +void Keys::registerWindow(Window win, FbTk::EventHandler &h, int context) { m_window_map[win] = context; + m_handler_map[win] = &h; grabWindow(win); } @@ -437,6 +439,7 @@ void Keys::registerWindow(Window win, int context) { void Keys::unregisterWindow(Window win) { FbTk::KeyUtil::ungrabKeys(win); FbTk::KeyUtil::ungrabButtons(win); + m_handler_map.erase(win); m_window_map.erase(win); } @@ -459,6 +462,13 @@ void Keys::keyMode(string keyMode) { void Keys::setKeyMode(t_key *keyMode) { ungrabKeys(); ungrabButtons(); + + // notify handlers that their buttons have been ungrabbed + HandlerMap::iterator h_it = m_handler_map.begin(), + h_it_end = m_handler_map.end(); + for (; h_it != h_it_end; ++h_it) + h_it->second->grabButtons(); + keylist_t::iterator it = keyMode->keylist.begin(); keylist_t::iterator it_end = keyMode->keylist.end(); for (; it != it_end; ++it) { diff --git a/src/Keys.hh b/src/Keys.hh index 2fca460..a8684ed 100644 --- a/src/Keys.hh +++ b/src/Keys.hh @@ -34,6 +34,10 @@ #include "FbTk/Command.hh" #include "FbTk/KeyUtil.hh" +namespace FbTk { + class EventHandler; +} + class Keys:private FbTk::NotCopyable { public: @@ -78,7 +82,7 @@ public: 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); + void registerWindow(Window win, FbTk::EventHandler &handler, int context); /// unregister window void unregisterWindow(Window win); @@ -145,7 +149,9 @@ private: Display *m_display; ///< display connection typedef std::map WindowMap; + typedef std::map HandlerMap; WindowMap m_window_map; + HandlerMap m_handler_map; }; #endif // KEYS_HH diff --git a/src/Screen.cc b/src/Screen.cc index 1557409..0c26a70 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -431,7 +431,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm, evm->add(*this, rootWindow()); Keys *keys = Fluxbox::instance()->keys(); if (keys) - keys->registerWindow(rootWindow().window(), + keys->registerWindow(rootWindow().window(), *this, Keys::GLOBAL|Keys::ON_DESKTOP); rootWindow().setCursor(XCreateFontCursor(disp, XC_left_ptr)); diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 54ee239..32925de 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -280,7 +280,7 @@ 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(), + Fluxbox::instance()->keys()->registerWindow(window().window(), *this, Keys::ON_TOOLBAR); // get everything together reconfigure(); diff --git a/src/Window.cc b/src/Window.cc index 78b30c2..0fb8673 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -289,7 +289,7 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbWinFrameTheme &tm, screen().focusControl().addFocusWinBack(*this); Fluxbox::instance()->keys()->registerWindow(frame().window().window(), - Keys::ON_WINDOW); + *this, Keys::ON_WINDOW); } @@ -479,8 +479,6 @@ void FluxboxWindow::init() { applyDecorations(true); - grabButtons(); - restoreAttributes(); if (m_workspace_number >= screen().numberOfWorkspaces()) @@ -1062,9 +1060,6 @@ void FluxboxWindow::reconfigure() { moveResize(frame().x(), frame().y(), frame().width(), frame().height()); - grabButtons(); - - frame().setDoubleClickTime(Fluxbox::instance()->getDoubleClickInterval()); m_timer.setTimeout(Fluxbox::instance()->getAutoRaiseDelay()); updateButtons(); @@ -1072,29 +1067,6 @@ void FluxboxWindow::reconfigure() { menu().reconfigure(); - typedef FbTk::RefCount CommandRef; - typedef FbTk::SimpleCommand WindowCmd; - CommandRef shade_on_cmd(new WindowCmd(*this, &FluxboxWindow::shadeOn)); - CommandRef shade_off_cmd(new WindowCmd(*this, &FluxboxWindow::shadeOff)); - CommandRef next_tab_cmd(new WindowCmd(*this, &FluxboxWindow::nextClient)); - CommandRef prev_tab_cmd(new WindowCmd(*this, &FluxboxWindow::prevClient)); - CommandRef null_cmd; - - int reverse = 0; - if (screen().getScrollReverse()) - reverse = 1; - - if (StringUtil::toLower(screen().getScrollAction()) == string("shade")) { - frame().setOnClickTitlebar(shade_on_cmd, 5 - reverse); // shade on mouse roll - frame().setOnClickTitlebar(shade_off_cmd, 4 + reverse); // unshade if rolled oposite direction - } else if (StringUtil::toLower(screen().getScrollAction()) == string("nexttab")) { - frame().setOnClickTitlebar(next_tab_cmd, 5 - reverse); // next tab - frame().setOnClickTitlebar(prev_tab_cmd, 4 + reverse); // previous tab - } else { - frame().setOnClickTitlebar(null_cmd, 4); - frame().setOnClickTitlebar(null_cmd, 5); - } - Client2ButtonMap::iterator it = m_labelbuttons.begin(), it_end = m_labelbuttons.end(); for (; it != it_end; ++it) @@ -2584,14 +2556,20 @@ void FluxboxWindow::buttonPressEvent(XButtonEvent &be) { return; } - // check frame events first - frame().buttonPressEvent(be); - + frame().tabcontainer().tryButtonPressEvent(be); if (be.button == 1) { if (!m_focused && acceptsFocus()) //check focus focus(); - if (frame().window().window() == be.window || frame().tabcontainer().window() == be.window) { + // click on titlebar + if (frame().gripLeft().window() != be.window && + frame().gripRight().window() != be.window && + frame().clientArea().window() != be.window && + frame().window() != be.window) + raise(); + + if (frame().window().window() == be.window || + frame().tabcontainer().window() == be.window) { if (screen().clickRaises()) raise(); #ifdef DEBUG @@ -2618,8 +2596,44 @@ void FluxboxWindow::buttonReleaseEvent(XButtonEvent &re) { stopResizing(); else if (m_attaching_tab) attachTo(re.x_root, re.y_root); - else - frame().buttonReleaseEvent(re); + else { + frame().tabcontainer().tryButtonReleaseEvent(re); + if (frame().gripLeft().window() == re.window || + frame().gripRight().window() == re.window || + frame().clientArea().window() == re.window || + frame().handle().window() == re.window || + frame().window() == re.window) + return; + + static Time last_release_time = 0; + bool double_click = (re.time - last_release_time <= + Fluxbox::instance()->getDoubleClickInterval()); + last_release_time = re.time; + + if (re.button == 1 && double_click) + shade(); + if (re.button == 3) + popupMenu(); + if (re.button == 2) + lower(); + + unsigned int reverse = (screen().getScrollReverse() ? 1 : 0); + if (re.button == 4 || re.button == 5) { + if (StringUtil::toLower(screen().getScrollAction()) == "shade") { + if (re.button == 5 - reverse) + shadeOn(); + else + shadeOff(); + } + if (StringUtil::toLower(screen().getScrollAction()) == "nexttab") { + if (re.button == 5 - reverse) + nextClient(); + else + prevClient(); + } + } + } + } @@ -3774,19 +3788,6 @@ void FluxboxWindow::setupWindow() { // we allow both to be done at once to share the commands using namespace FbTk; - typedef RefCount CommandRef; - typedef SimpleCommand WindowCmd; - - CommandRef shade_cmd(new WindowCmd(*this, &FluxboxWindow::shade)); - CommandRef shade_on_cmd(new WindowCmd(*this, &FluxboxWindow::shadeOn)); - CommandRef shade_off_cmd(new WindowCmd(*this, &FluxboxWindow::shadeOff)); - CommandRef next_tab_cmd(new WindowCmd(*this, &FluxboxWindow::nextClient)); - CommandRef prev_tab_cmd(new WindowCmd(*this, &FluxboxWindow::prevClient)); - CommandRef lower_cmd(new WindowCmd(*this, &FluxboxWindow::lower)); - CommandRef raise_and_focus_cmd(new WindowCmd(*this, &FluxboxWindow::raiseAndFocus)); - CommandRef stick_cmd(new WindowCmd(*this, &FluxboxWindow::stick)); - CommandRef show_menu_cmd(new WindowCmd(*this, &FluxboxWindow::popupMenu)); - typedef FbTk::Resource > WinButtonsResource; string titlebar_name[2]; @@ -3842,26 +3843,6 @@ void FluxboxWindow::setupWindow() { updateButtons(); - // setup titlebar - frame().setOnClickTitlebar(raise_and_focus_cmd, 1, false, true); // on press with button 1 - frame().setOnClickTitlebar(shade_cmd, 1, true); // doubleclick with button 1 - frame().setOnClickTitlebar(show_menu_cmd, 3); // on release with button 3 - frame().setOnClickTitlebar(lower_cmd, 2); // on release with button 2 - - int reverse = 0; - if (screen().getScrollReverse()) - reverse = 1; - - if (StringUtil::toLower(screen().getScrollAction()) == string("shade")) { - frame().setOnClickTitlebar(shade_on_cmd, 5 - reverse); // shade on mouse roll - frame().setOnClickTitlebar(shade_off_cmd, 4 + reverse); // unshade if rolled oposite direction - } else if (StringUtil::toLower(screen().getScrollAction()) == string("nexttab")) { - frame().setOnClickTitlebar(next_tab_cmd, 5 - reverse); // next tab - frame().setOnClickTitlebar(prev_tab_cmd, 4 + reverse); // previous tab - } - - frame().setDoubleClickTime(Fluxbox::instance()->getDoubleClickInterval()); - // end setup frame } -- cgit v0.11.2