From 0a14d911c64a8f6378665bf3e49b868b9175b51f Mon Sep 17 00:00:00 2001 From: Mark Tiefenbruck <mark@fluxbox.org> Date: Thu, 20 Dec 2007 23:07:46 -0800 Subject: added key command StartTabbing --- ChangeLog | 3 + data/init.in | 2 +- data/keys | 3 + src/CurrentWindowCmd.cc | 10 +++ src/CurrentWindowCmd.hh | 8 +++ src/Window.cc | 149 ++++++++++++++++++++--------------------- src/Window.hh | 2 + src/fluxbox.cc | 2 +- util/fluxbox-update_configs.cc | 13 ++++ 9 files changed, 114 insertions(+), 78 deletions(-) diff --git a/ChangeLog b/ChangeLog index 91975b2..3f39d79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ (Format: Year/Month/Day) Changes for 1.0.1: +*07/12/21: + * Added new key command :StartTabbing (Mark) + Window.cc/hh CurrentWindowCmd.cc/hh *07/12/20: * Added new key command :ForEach (or :Map) (Mark) - :ForEach {<command>} [{ [{<list opts>}] [<bool command>] }] diff --git a/data/init.in b/data/init.in index c0bb93a..86cfa08 100644 --- a/data/init.in +++ b/data/init.in @@ -30,4 +30,4 @@ session.colorsPerChannel: 4 session.doubleClickInterval: 250 session.cacheMax: 200 session.imageDither: True -session.configVersion: 6 +session.configVersion: 7 diff --git a/data/keys b/data/keys index a8c7cba..8b2a234 100644 --- a/data/keys +++ b/data/keys @@ -15,6 +15,9 @@ OnToolbar Mouse5 :PrevWorkspace OnWindow Mod1 Mouse1 :StartMoving OnWindow Mod1 Mouse3 :StartResizing +# middle click a window's titlebar and drag to attach windows +OnTitlebar Mouse2 :StartTabbing + # double click on the titlebar to shade OnTitlebar Double Mouse1 :Shade diff --git a/src/CurrentWindowCmd.cc b/src/CurrentWindowCmd.cc index d7b05ab..072f3c5 100644 --- a/src/CurrentWindowCmd.cc +++ b/src/CurrentWindowCmd.cc @@ -313,6 +313,16 @@ void StartResizingCmd::real_execute() { } } +REGISTER_OBJECT(starttabbing, StartTabbingCmd, Command); + +void StartTabbingCmd::real_execute() { + const XEvent &last = Fluxbox::instance()->lastEvent(); + if (last.type == ButtonPress) { + const XButtonEvent &be = last.xbutton; + fbwindow().startTabbing(be); + } +} + FbTk::Command *MoveCmd::parse(const string &command, const string &args, bool trusted) { FbTk_istringstream is(args.c_str()); diff --git a/src/CurrentWindowCmd.hh b/src/CurrentWindowCmd.hh index 7ef1184..fdce8d6 100644 --- a/src/CurrentWindowCmd.hh +++ b/src/CurrentWindowCmd.hh @@ -159,6 +159,14 @@ private: const FluxboxWindow::ResizeModel m_mode; }; +// begin tabbing with mouse +class StartTabbingCmd: public WindowHelperCmd { +public: + StartTabbingCmd() { } +protected: + void real_execute(); +}; + // move cmd, relative position class MoveCmd: public WindowHelperCmd { public: diff --git a/src/Window.cc b/src/Window.cc index c9ab1b2..d99d1c1 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -2611,11 +2611,10 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { me.window = frame().window().window(); } - bool inside_titlebar = (frame().titlebar() == me.window - || frame().label() == me.window - || frame().tabcontainer() == me.window - || frame().handle() == me.window - || frame().window() == me.window); + bool inside_titlebar = frame().gripLeft().window() != me.window && + frame().gripRight().window() != me.window && + frame().clientArea().window() != me.window && + frame().window() != me.window; if (Fluxbox::instance()->getIgnoreBorder() && m_attaching_tab == 0 && !(isMoving() || isResizing())) { @@ -2650,24 +2649,8 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { return; } - WinClient *client = 0; - if (!inside_titlebar) { - // determine if we're in titlebar - Client2ButtonMap::iterator it = - find_if(m_labelbuttons.begin(), - m_labelbuttons.end(), - Compose(bind2nd(equal_to<Window>(), me.window), - Compose(mem_fun(&TextButton::window), - Select2nd<Client2ButtonMap::value_type>()))); - if (it != m_labelbuttons.end()) { - inside_titlebar = true; - client = (*it).first; - } - } - - if ((me.state & Button1Mask) && functions.move && - inside_titlebar && - !isResizing()) { + if (moving || (me.state & Button1Mask) && functions.move && + inside_titlebar && !isResizing() && m_attaching_tab == 0) { if (! isMoving()) { startMoving(me.x_root, me.y_root); @@ -2741,7 +2724,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { screen().showPosition(dx, dy); } // end if moving - } else if (functions.resize && + } else if (resizing || m_attaching_tab == 0 && functions.resize && (((me.state & Button1Mask) && (me.window == frame().gripRight() || me.window == frame().gripLeft())) || @@ -2833,61 +2816,25 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { screen().showGeometry(gx, gy); } } - } else if (functions.tabable && - (me.state & Button2Mask) && inside_titlebar && (client != 0 || m_attaching_tab != 0)) { + } else if (m_attaching_tab != 0) { // // drag'n'drop code for tabs // - FbTk::TextButton &active_button = *m_labelbuttons[(m_attaching_tab==0)?client:m_attaching_tab]; - if (m_attaching_tab == 0) { - if (s_num_grabs > 0) - return; - // start drag'n'drop for tab - m_attaching_tab = client; - grabPointer(me.window, False, ButtonMotionMask | - ButtonReleaseMask, GrabModeAsync, GrabModeAsync, - None, frame(). theme().moveCursor(), CurrentTime); - // relative position on button - m_button_grab_x = me.x; - m_button_grab_y = me.y; - // last known root mouse position - m_last_move_x = me.x_root - me.x; - m_last_move_y = me.y_root - me.y; - // hijack extra vars for initial grab location - m_last_resize_x = me.x_root; - m_last_resize_y = me.y_root; - - Fluxbox::instance()->grab(); - - parent().drawRectangle(screen().rootTheme().opGC(), - m_last_move_x, m_last_move_y, - active_button.width(), - active_button.height()); - - menu().hide(); - } else { - // we already grabed and started to drag'n'drop tab - // so we update drag'n'drop-rectangle - int dx = me.x_root - m_button_grab_x, dy = me.y_root - m_button_grab_y; - - //erase rectangle - parent().drawRectangle(screen().rootTheme().opGC(), - m_last_move_x, m_last_move_y, - active_button.width(), - active_button.height()); - - - // redraw rectangle at new pos - m_last_move_x = dx; - m_last_move_y = dy; - parent().drawRectangle(screen().rootTheme().opGC(), - m_last_move_x, m_last_move_y, - active_button.width(), - active_button.height()); + // we already grabed and started to drag'n'drop tab + // so we update drag'n'drop-rectangle + int dx = me.x_root - m_button_grab_x, dy = me.y_root - m_button_grab_y; + parent().drawRectangle(screen().rootTheme().opGC(), + m_last_move_x, m_last_move_y, + m_last_resize_w, m_last_resize_h); + parent().drawRectangle(screen().rootTheme().opGC(), + dx, dy, + m_last_resize_w, m_last_resize_h); - } + // change remembered position of rectangle + m_last_move_x = dx; + m_last_move_y = dy; } } @@ -3116,7 +3063,7 @@ void FluxboxWindow::startMoving(int x, int y) { Fluxbox *fluxbox = Fluxbox::instance(); // grabbing (and masking) on the root window allows us to // freely map and unmap the window we're moving. - grabPointer(screen().rootWindow().window(), False, Button1MotionMask | + grabPointer(screen().rootWindow().window(), False, ButtonMotionMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, screen().rootWindow().window(), frame().theme().moveCursor(), CurrentTime); @@ -3467,14 +3414,64 @@ void FluxboxWindow::stopResizing(bool interrupted) { ungrabPointer(CurrentTime); } +void FluxboxWindow::startTabbing(const XButtonEvent &be) { + + if (s_num_grabs > 0) + return; + + m_attaching_tab = 0; + // determine if we're in titlebar + Client2ButtonMap::iterator it = + find_if(m_labelbuttons.begin(), + m_labelbuttons.end(), + Compose(bind2nd(equal_to<Window>(), be.window), + Compose(mem_fun(&TextButton::window), + Select2nd<Client2ButtonMap::value_type>()))); + if (it != m_labelbuttons.end()) + m_attaching_tab = it->first; + + // start drag'n'drop for tab + grabPointer(be.window, False, ButtonMotionMask | + ButtonReleaseMask, GrabModeAsync, GrabModeAsync, + None, frame().theme().moveCursor(), CurrentTime); + + // relative position on the button + m_button_grab_x = be.x; + m_button_grab_y = be.y; + // position of the button + m_last_move_x = be.x_root - be.x; + m_last_move_y = be.y_root - be.y; + // hijack extra vars for initial grab location + m_last_resize_x = be.x_root; + m_last_resize_y = be.y_root; + + Fluxbox::instance()->grab(); + + if (m_attaching_tab) { + FbTk::TextButton &active_button = *m_labelbuttons[m_attaching_tab]; + m_last_resize_w = active_button.width(); + m_last_resize_h = active_button.height(); + } else { + m_attaching_tab = m_client; + unsigned int bw = 2*frame().window().borderWidth()-1; + m_last_resize_w = frame().width() + bw; + m_last_resize_h = frame().height() + bw; + } + + parent().drawRectangle(screen().rootTheme().opGC(), + m_last_move_x, m_last_move_y, + m_last_resize_w, m_last_resize_h); + + menu().hide(); +} + void FluxboxWindow::attachTo(int x, int y, bool interrupted) { if (m_attaching_tab == 0) return; parent().drawRectangle(screen().rootTheme().opGC(), m_last_move_x, m_last_move_y, - m_labelbuttons[m_attaching_tab]->width(), - m_labelbuttons[m_attaching_tab]->height()); + m_last_resize_w, m_last_resize_h); ungrabPointer(CurrentTime); diff --git a/src/Window.hh b/src/Window.hh index 821e86a..66c6f2b 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -393,6 +393,8 @@ public: ResizeDirection getResizeDirection(int x, int y, ResizeModel model); /// stops the resizing void stopResizing(bool interrupted = false); + /// starts tabbing + void startTabbing(const XButtonEvent &be); /** @name accessors diff --git a/src/fluxbox.cc b/src/fluxbox.cc index 9deb39b..341fda8 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -643,7 +643,7 @@ void Fluxbox::setupConfigFiles() { if (create_init) FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str()); -#define CONFIG_VERSION 6 +#define CONFIG_VERSION 7 FbTk::Resource<int> 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 921530a..75be474 100644 --- a/util/fluxbox-update_configs.cc +++ b/util/fluxbox-update_configs.cc @@ -275,6 +275,19 @@ int run_updates(int old_version, FbTk::ResourceManager &rm) { new_version = 6; } + if (old_version < 7) { // added StartTabbing command + string whole_keyfile = read_file(keyfilename); + string new_keyfile = ""; + // let's put our new keybindings first, so they're easy to find + new_keyfile += "# start tabbing windows together\n"; + new_keyfile += "OnTitlebar Mouse2 :StartTabbing\n\n"; + new_keyfile += whole_keyfile; // don't forget user's old keybindings + + write_file(keyfilename, new_keyfile); + + new_version = 7; + } + return new_version; } -- cgit v0.11.2