all repos — fluxbox @ bf75608df0025d49ea0f52326a402825fcc55d06

custom fork of the fluxbox windowmanager

menu delay and mode
fluxgen fluxgen
commit

bf75608df0025d49ea0f52326a402825fcc55d06

parent

624fd1e1215812057ef4d1322cafe587717a3bf8

6 files changed, 170 insertions(+), 35 deletions(-)

jump to
M src/FbTk/Menu.ccsrc/FbTk/Menu.cc

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Menu.cc,v 1.45 2003/12/10 23:33:15 fluxgen Exp $ +// $Id: Menu.cc,v 1.46 2003/12/12 18:18:49 fluxgen Exp $ //use GNU extensions #ifndef _GNU_SOURCE

@@ -37,6 +37,7 @@ #include "MenuTheme.hh"

#include "App.hh" #include "EventManager.hh" #include "Transparent.hh" +#include "SimpleCommand.hh" #include <X11/Xatom.h> #include <X11/keysym.h>

@@ -64,6 +65,17 @@ m_alignment(ALIGNDONTCARE),

m_border_width(0), m_themeobserver(*this), m_need_update(true) { + + // setup timers + + RefCount<Command> show_cmd(new SimpleCommand<Menu>(*this, &Menu::openSubmenu)); + m_submenu_timer.setCommand(show_cmd); + m_submenu_timer.fireOnce(true); + + + RefCount<Command> hide_cmd(new SimpleCommand<Menu>(*this, &Menu::closeMenu)); + m_hide_timer.setCommand(hide_cmd); + m_hide_timer.fireOnce(true); // make sure we get updated when the theme is reloaded tm.addListener(m_themeobserver);

@@ -673,7 +685,7 @@ }

if (m_alignment == ALIGNBOTTOM && (y + item->submenu()->height()) > ((shifted) ? menu.y_shift : - menu.y) + height()) { + menu.y) + height()) { y = (((shifted) ? menu.y_shift : menu.y) + height() - item->submenu()->height()); }

@@ -864,23 +876,23 @@ }

} } else if (item->isToggleItem() && m_theme.unselectedPixmap().pixmap().drawable() != 0) { - // enable clip mask - XSetClipMask(FbTk::App::instance()->display(), - gc, - m_theme.unselectedPixmap().mask().drawable()); - XSetClipOrigin(FbTk::App::instance()->display(), - gc, sel_x, item_y); - // copy bullet pixmap to frame - m_frame_pm.copyArea(m_theme.unselectedPixmap().pixmap().drawable(), - gc, - 0, 0, - sel_x, item_y, - m_theme.unselectedPixmap().width(), - m_theme.unselectedPixmap().height()); - // disable clip mask - XSetClipMask(FbTk::App::instance()->display(), - gc, - None); + // enable clip mask + XSetClipMask(FbTk::App::instance()->display(), + gc, + m_theme.unselectedPixmap().mask().drawable()); + XSetClipOrigin(FbTk::App::instance()->display(), + gc, sel_x, item_y); + // copy bullet pixmap to frame + m_frame_pm.copyArea(m_theme.unselectedPixmap().pixmap().drawable(), + gc, + 0, 0, + sel_x, item_y, + m_theme.unselectedPixmap().width(), + m_theme.unselectedPixmap().height()); + // disable clip mask + XSetClipMask(FbTk::App::instance()->display(), + gc, + None); } if (dotext && text) {

@@ -1109,6 +1121,7 @@ }

void Menu::motionNotifyEvent(XMotionEvent &me) { + m_hide_timer.stop(); if (me.window == menu.title && (me.state & Button1Mask)) { if (movable) { if (! moving) {

@@ -1128,7 +1141,7 @@

menu.window.move(menu.x, menu.y); // if (which_sub >= 0) - // drawSubmenu(which_sub); + // drawSubmenu(which_sub); } } } else if ((! (me.state & Button1Mask)) && me.window == menu.frame &&

@@ -1139,21 +1152,28 @@ w = (sbl * menu.persub) + i;

if ((i != which_press || sbl != which_sbl) && (w < static_cast<int>(menuitems.size()) && w >= 0)) { + if (which_press != -1 && which_sbl != -1) { + int p = which_sbl * menu.persub + which_press; MenuItem *item = menuitems[p]; + // don't redraw disabled items on enter/leave + if (item != 0 && item->isEnabled()) { - // don't redraw disabled items on enter/leave - if (item->isEnabled()) { drawItem(p, false, true, true); + if (item->submenu()) { + if (item->submenu()->isVisible() && - (! item->submenu()->isTorn())) { - item->submenu()->internal_hide(); + !item->submenu()->isTorn()) { which_sub = -1; + // setup hide timer for submenu + item->submenu()->startHide(); } } + } + } which_press = i;

@@ -1162,11 +1182,27 @@

MenuItem *itmp = menuitems[w]; if (itmp->submenu()) { - if (!itmp->submenu()->isVisible()) - drawSubmenu(w); - } else + + drawItem(w, true); + + if (theme().menuMode() == MenuTheme::DELAY_OPEN) { + cerr<<"menuMode DELAY_OPEN"<<endl; + // setup show menu timer + stopHide(); + + timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = theme().delayOpen(); + m_submenu_timer.setTimeout(timeout); + m_submenu_timer.start(); + + } + + } else { + m_submenu_timer.stop(); if (itmp->isEnabled()) drawItem(w, true, true, true); + } } } }

@@ -1345,6 +1381,41 @@

void Menu::renderTransFrame() { menu.frame.clear(); menu.frame.updateTransparent(); +} + +void Menu::openSubmenu() { + if (!isVisible() || which_press < 0 || which_press >= menuitems.size() || + which_sbl < 0 || which_sbl >= menuitems.size()) + return; + + int item = which_sbl * menu.persub + which_press; + if (item < 0 || item >= menuitems.size()) + return; + + stopHide(); + + if (menuitems[item]->submenu() != 0 && !menuitems[item]->submenu()->isVisible()) + drawSubmenu(item); + +} + +void Menu::closeMenu() { + if (isVisible() && + !isTorn()) { + internal_hide(); + } +} + +void Menu::startHide() { + timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = theme().delayClose(); + m_hide_timer.setTimeout(timeout); + m_hide_timer.start(); +} + +void Menu::stopHide() { + m_hide_timer.stop(); } }; // end namespace FbTk
M src/FbTk/Menu.hhsrc/FbTk/Menu.hh

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Menu.hh,v 1.25 2003/12/10 23:08:06 fluxgen Exp $ +// $Id: Menu.hh,v 1.26 2003/12/12 18:18:49 fluxgen Exp $ #ifndef FBTK_MENU_HH #define FBTK_MENU_HH

@@ -39,6 +39,7 @@ #include "Command.hh"

#include "Observer.hh" #include "FbPixmap.hh" #include "MenuTheme.hh" +#include "Timer.hh" namespace FbTk {

@@ -174,6 +175,11 @@ inline Menu *parent() { return m_parent; }

inline const Menu *parent() const { return m_parent; } private: + void openSubmenu(); + void closeMenu(); + void startHide(); + void stopHide(); + void renderTransFrame(); typedef std::vector<MenuItem *> Menuitems;

@@ -215,6 +221,8 @@ Drawable m_root_pm;

static Menu *s_focused; ///< holds current input focused menu, so one can determine if a menu is focused FbPixmap m_frame_pm; bool m_need_update; + Timer m_submenu_timer; + Timer m_hide_timer; }; }; // end namespace FbTk
M src/FbTk/MenuTheme.ccsrc/FbTk/MenuTheme.cc

@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: MenuTheme.cc,v 1.11 2003/09/12 23:32:02 fluxgen Exp $ +// $Id: MenuTheme.cc,v 1.12 2003/12/12 18:18:49 fluxgen Exp $ #include "MenuTheme.hh"

@@ -60,6 +60,9 @@ f_text_gc(RootWindow(m_display, screen_num)),

h_text_gc(RootWindow(m_display, screen_num)), d_text_gc(RootWindow(m_display, screen_num)), hilite_gc(RootWindow(m_display, screen_num)), + m_menumode(DELAY_OPEN), + m_delayopen(0), // no delay as default + m_delayclose(0), // no delay as default m_alpha(255) { // set default values
M src/FbTk/MenuTheme.hhsrc/FbTk/MenuTheme.hh

@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: MenuTheme.hh,v 1.10 2003/11/28 22:53:10 fluxgen Exp $ +// $Id: MenuTheme.hh,v 1.11 2003/12/12 18:18:49 fluxgen Exp $ #ifndef FBTK_MENUTHEME_HH #define FBTK_MENUTHEME_HH

@@ -37,6 +37,11 @@ namespace FbTk {

class MenuTheme:public FbTk::Theme { public: + //!! TODO + // this isn't actually used with a theme item + // see setMenuMode() for more info + enum MenuMode {CLICK_OPEN, DELAY_OPEN}; + enum BulletType { EMPTY, SQUARE, TRIANGLE, DIAMOND}; MenuTheme(int screen_num); virtual ~MenuTheme();

@@ -102,7 +107,16 @@ unsigned int bevelWidth() const { return *m_bevel_width; }

inline unsigned char alpha() const { return m_alpha; } void setAlpha(unsigned char alpha) { m_alpha = alpha; } - + // this isn't actually a theme item + // but we'll let it be here for now, until there's a better way to + // get resources into menu + void setMenuMode(MenuMode mode) { m_menumode = mode; } + MenuMode menuMode() const { return m_menumode; } + void setDelayOpen(int usec) { m_delayopen = usec; } + void setDelayClose(int usec) { m_delayclose = usec; } + int delayOpen() const { return m_delayopen; } + int delayClose() const { return m_delayclose; } + const FbTk::Color &borderColor() const { return *m_border_color; } FbTk::Subject &themeChangeSig() { return m_theme_change_sig; } /// attach observer

@@ -126,6 +140,10 @@ FbTk::GContext t_text_gc, f_text_gc, h_text_gc, d_text_gc, hilite_gc;

FbTk::Subject m_theme_change_sig; unsigned char m_alpha; + MenuMode m_menumode; + unsigned int m_delayopen; ///< in usec + unsigned int m_delayclose; ///< in usec + }; }; // end namespace FbTk
M src/Screen.ccsrc/Screen.cc

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.cc,v 1.247 2003/12/10 23:08:03 fluxgen Exp $ +// $Id: Screen.cc,v 1.248 2003/12/12 18:18:12 fluxgen Exp $ #include "Screen.hh"

@@ -154,7 +154,31 @@

}; // End anonymous namespace +template <> +void FbTk::Resource<FbTk::MenuTheme::MenuMode>::setDefaultValue() { + *(*this) = FbTk::MenuTheme::DELAY_OPEN; +} +template <> +string FbTk::Resource<FbTk::MenuTheme::MenuMode>::getString() { + switch (*(*this)) { + case FbTk::MenuTheme::DELAY_OPEN: + return string("Delay"); + case FbTk::MenuTheme::CLICK_OPEN: + return string("Click"); + } + return string("Delay"); +} + +template <> +void FbTk::Resource<FbTk::MenuTheme::MenuMode>::setFromString(const char *str) { + if (strcasecmp(str, "Delay") == 0) + *(*this) = FbTk::MenuTheme::DELAY_OPEN; + else if (strcasecmp(str, "Click") == 0) + *(*this) = FbTk::MenuTheme::CLICK_OPEN; + else + setDefaultValue(); +} namespace {

@@ -222,7 +246,10 @@ resizemode(rm, "", scrname+".resizeMode", altscrname+".ResizeMode"),

focus_model(rm, Fluxbox::CLICKTOFOCUS, scrname+".focusModel", altscrname+".FocusModel"), workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"), edge_snap_threshold(rm, 0, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"), - menu_alpha(rm, 255, scrname+".menuAlpha", altscrname+".MenuAlpha") { + menu_alpha(rm, 255, scrname+".menuAlpha", altscrname+".MenuAlpha"), + menu_delay(rm, 0, scrname + ".menuDelay", altscrname+".MenuDelay"), + menu_delay_close(rm, 0, scrname + ".menuDelayClose", altscrname+".MenuDelayClose"), + menu_mode(rm, FbTk::MenuTheme::DELAY_OPEN, scrname+".menuMode", altscrname+".MenuMode") { };

@@ -307,6 +334,9 @@ #endif // SLIT

m_menutheme->setAlpha(*resource.menu_alpha); + m_menutheme->setMenuMode(*resource.menu_mode); + m_menutheme->setDelayOpen(*resource.menu_delay); + m_menutheme->setDelayClose(*resource.menu_delay_close); imageControl().setDither(*resource.image_dither);

@@ -570,6 +600,10 @@ }

void BScreen::reconfigure() { m_menutheme->setAlpha(*resource.menu_alpha); + m_menutheme->setMenuMode(*resource.menu_mode); + m_menutheme->setDelayOpen(*resource.menu_delay); + m_menutheme->setDelayClose(*resource.menu_delay_close); + Fluxbox::instance()->loadRootCommand(*this); // setup windowtheme, toolbartheme for antialias
M src/Screen.hhsrc/Screen.hh

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.hh,v 1.126 2003/12/10 23:08:03 fluxgen Exp $ +// $Id: Screen.hh,v 1.127 2003/12/12 18:18:12 fluxgen Exp $ #ifndef SCREEN_HH #define SCREEN_HH

@@ -430,7 +430,8 @@ FbTk::Resource<std::string> rootcommand;

FbTk::Resource<std::string> resizemode; FbTk::Resource<Fluxbox::FocusModel> focus_model; bool ordered_dither; - FbTk::Resource<int> workspaces, edge_snap_threshold, menu_alpha; + FbTk::Resource<int> workspaces, edge_snap_threshold, menu_alpha, menu_delay, menu_delay_close; + FbTk::Resource<FbTk::MenuTheme::MenuMode> menu_mode; int placement_policy, row_direction, col_direction;