From 1583beb95327e2f04fe293ce598f2714db66861b Mon Sep 17 00:00:00 2001 From: Mathias Gumz Date: Fri, 25 Feb 2011 11:55:06 +0100 Subject: first draft of the 'SingleTrigger' feature for menus using the type-a-head feature of the fluxbox-menu creates a number of matches (if there are any). with enabled 'SingleTrigger' the user triggers that match instantly without any further ado. a menu inherits the 'SingleTrigger' setting of its parent. new resources for .fluxbox/init: menu.window.singleTrigger: true|false menu.root.singleTrigger: true|false menu.workspace.singleTrigger: true|false --- src/FbTk/Menu.cc | 58 ++++++++++++++++++++++++++++++++++++-------------------- src/FbTk/Menu.hh | 4 ++++ src/Screen.cc | 26 +++++++++++++++++-------- src/Screen.hh | 20 ++++++++++++------- 4 files changed, 72 insertions(+), 36 deletions(-) diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc index 40f81c8..7128152 100644 --- a/src/FbTk/Menu.cc +++ b/src/FbTk/Menu.cc @@ -109,7 +109,8 @@ Menu::Menu(FbTk::ThemeProxy &tm, ImageControl &imgctrl): m_alignment(ALIGNDONTCARE), m_active_index(-1), m_shape(0), - m_need_update(true) { + m_need_update(true), + m_single_trigger(false) { // setup timers RefCount > show_cmd(new SimpleCommand(*this, &Menu::openSubmenu)); @@ -861,6 +862,10 @@ bool Menu::isItemSelectable(unsigned int index) const { return (!item || !item->isEnabled()) ? false : true; } +bool Menu::isSingleTrigger() const { + + return m_single_trigger || (parent() && parent()->isSingleTrigger()); +} void Menu::handleEvent(XEvent &event) { if (event.type == FocusOut) { @@ -1123,19 +1128,7 @@ void Menu::keyPressEvent(XKeyEvent &event) { break; case XK_KP_Enter: case XK_Return: - resetTypeAhead(); - if (validIndex(m_active_index) && - isItemEnabled(m_active_index)) { - // send fake button click - int button = (event.state & ShiftMask) ? 3 : 1; - if (menuitems[m_active_index]->submenu() != 0 && button == 1) - enterSubmenu(); - else { - find(m_active_index)->click(button, event.time, event.state); - m_need_update = true; - updateMenu(); - } - } + goto click_on_item; break; case XK_Tab: case XK_ISO_Left_Tab: @@ -1150,15 +1143,38 @@ void Menu::keyPressEvent(XKeyEvent &event) { drawTypeAheadItems(); break; default: - m_type_ahead.putCharacter(keychar[0]); - // if current item doesn't match new search string, find the next one - drawTypeAheadItems(); - if (!m_matches.empty() && (!validIndex(m_active_index) || - std::find(m_matches.begin(), m_matches.end(), - find(m_active_index)) == m_matches.end())) - cycleItems(false); + { + m_type_ahead.putCharacter(keychar[0]); + drawTypeAheadItems(); + // if current item doesn't match new search string, find the next one + if (!m_matches.empty() && (!validIndex(m_active_index) || + std::find(m_matches.begin(), m_matches.end(), + find(m_active_index)) == m_matches.end())) + cycleItems(false); + + if (isSingleTrigger() && m_matches.size() == 1) { + goto click_on_item; + } + } break; } + return; + +// TODO: 'goto' is just the temporary solution to this code sharing +click_on_item: + resetTypeAhead(); + if (validIndex(m_active_index) && + isItemEnabled(m_active_index)) { + // send fake button click + int button = (event.state & ShiftMask) ? 3 : 1; + if (menuitems[m_active_index]->submenu() != 0 && button == 1) + enterSubmenu(); + else { + find(m_active_index)->click(button, event.time, event.state); + m_need_update = true; + updateMenu(); + } + } } void Menu::leaveNotifyEvent(XCrossingEvent &ce) { diff --git a/src/FbTk/Menu.hh b/src/FbTk/Menu.hh index bd830b4..114872b 100644 --- a/src/FbTk/Menu.hh +++ b/src/FbTk/Menu.hh @@ -91,6 +91,9 @@ public: void setScreen(int x, int y, int w, int h); + void setSingleTrigger(bool flag) { m_single_trigger = flag; }; + bool isSingleTrigger() const; + /** @name event handlers */ @@ -201,6 +204,7 @@ private: Menuitems menuitems; TypeAhead m_type_ahead; Menuitems m_matches; + bool m_single_trigger; void resetTypeAhead(); void drawTypeAheadItems(); diff --git a/src/Screen.cc b/src/Screen.cc index 86799da..a35a7eb 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -276,22 +276,30 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm, auto_raise(rm, true, scrname+".autoRaise", altscrname+".AutoRaise"), click_raises(rm, true, scrname+".clickRaises", altscrname+".ClickRaises"), default_deco(rm, "NORMAL", scrname+".defaultDeco", altscrname+".DefaultDeco"), - tab_placement(rm, FbWinFrame::TOPLEFT, scrname+".tab.placement", altscrname+".Tab.Placement"), - windowmenufile(rm, Fluxbox::instance()->getDefaultDataFilename("windowmenu"), scrname+".windowMenu", altscrname+".WindowMenu"), typing_delay(rm, 0, scrname+".noFocusWhileTypingDelay", altscrname+".NoFocusWhileTypingDelay"), workspaces(rm, 4, scrname+".workspaces", altscrname+".Workspaces"), edge_snap_threshold(rm, 10, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"), focused_alpha(rm, 255, scrname+".window.focus.alpha", altscrname+".Window.Focus.Alpha"), unfocused_alpha(rm, 255, scrname+".window.unfocus.alpha", altscrname+".Window.Unfocus.Alpha"), + + tooltip_delay(rm, 500, scrname + ".tooltipDelay", altscrname+".TooltipDelay"), + menu_alpha(rm, 255, scrname+".menu.alpha", altscrname+".Menu.Alpha"), menu_delay(rm, 200, scrname + ".menuDelay", altscrname+".MenuDelay"), - tab_width(rm, 64, scrname + ".tab.width", altscrname+".Tab.Width"), - tooltip_delay(rm, 500, scrname + ".tooltipDelay", altscrname+".TooltipDelay"), - allow_remote_actions(rm, false, scrname+".allowRemoteActions", altscrname+".AllowRemoteActions"), clientmenu_use_pixmap(rm, true, scrname+".clientMenu.usePixmap", altscrname+".ClientMenu.UsePixmap"), + windowmenufile(rm, Fluxbox::instance()->getDefaultDataFilename("windowmenu"), scrname+".windowMenu", altscrname+".WindowMenu"), + windowmenu_singletrigger(rm, false, scrname+".menu.window.singleTrigger", altscrname+".Menu.Window.SingleTrigger"), + rootmenu_singletrigger(rm, false, scrname+".menu.root.singleTrigger", altscrname+".Menu.Root.SingleTrigger"), + workspacemenu_singletrigger(rm, false, scrname+".menu.workspace.singleTrigger", altscrname+".Menu.Workspace.SingleTrigger"), + + tab_placement(rm, FbWinFrame::TOPLEFT, scrname+".tab.placement", altscrname+".Tab.Placement"), + tab_width(rm, 64, scrname + ".tab.width", altscrname+".Tab.Width"), tabs_use_pixmap(rm, true, scrname+".tabs.usePixmap", altscrname+".Tabs.UsePixmap"), max_over_tabs(rm, false, scrname+".tabs.maxOver", altscrname+".Tabs.MaxOver"), - default_internal_tabs(rm, true /* TODO: autoconf option? */ , scrname+".tabs.intitlebar", altscrname+".Tabs.InTitlebar") { + default_internal_tabs(rm, true /* TODO: autoconf option? */ , scrname+".tabs.intitlebar", altscrname+".Tabs.InTitlebar"), + + allow_remote_actions(rm, false, scrname+".allowRemoteActions", altscrname+".AllowRemoteActions") +{ } @@ -335,8 +343,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm, // TODO fluxgen: check if this is the right place (it was not -lis) // // Create the first one, initXinerama will expand this if needed. - m_head_areas.resize(1); - m_head_areas[0] = new HeadArea(); + m_head_areas.push_back(new HeadArea()); initXinerama(); @@ -1413,8 +1420,11 @@ void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id, void BScreen::initMenus() { m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber())); + m_workspacemenu->setSingleTrigger(*resource.workspacemenu_singletrigger); m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename()); + m_rootmenu->setSingleTrigger(*resource.rootmenu_singletrigger); m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename()); + m_windowmenu->setSingleTrigger(*resource.windowmenu_singletrigger); } diff --git a/src/Screen.hh b/src/Screen.hh index de3a5a1..52b075b 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -517,19 +517,25 @@ private: max_ignore_inc, max_disable_move, max_disable_resize, workspace_warping, show_window_pos, auto_raise, click_raises; FbTk::Resource default_deco; - FbTk::Resource tab_placement; - FbTk::Resource windowmenufile; FbTk::Resource typing_delay; - FbTk::Resource workspaces, edge_snap_threshold, focused_alpha, - unfocused_alpha, menu_alpha, menu_delay, - tab_width, tooltip_delay; - FbTk::Resource allow_remote_actions; + FbTk::Resource workspaces, edge_snap_threshold, + focused_alpha, unfocused_alpha, tooltip_delay; + + FbTk::Resource menu_alpha; + FbTk::Resource menu_delay; FbTk::Resource clientmenu_use_pixmap; + FbTk::Resource windowmenufile; + FbTk::Resource windowmenu_singletrigger; + FbTk::Resource rootmenu_singletrigger; + FbTk::Resource workspacemenu_singletrigger; + + FbTk::Resource tab_placement; + FbTk::Resource tab_width; FbTk::Resource tabs_use_pixmap; FbTk::Resource max_over_tabs; FbTk::Resource default_internal_tabs; - + FbTk::Resource allow_remote_actions; } resource; /// Holds manage resources that screen destroys -- cgit v0.11.2