aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--data/init.in2
-rw-r--r--data/keys3
-rw-r--r--src/CurrentWindowCmd.cc10
-rw-r--r--src/CurrentWindowCmd.hh8
-rw-r--r--src/Window.cc149
-rw-r--r--src/Window.hh2
-rw-r--r--src/fluxbox.cc2
-rw-r--r--util/fluxbox-update_configs.cc13
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 @@
1 (Format: Year/Month/Day) 1 (Format: Year/Month/Day)
2Changes for 1.0.1: 2Changes for 1.0.1:
3*07/12/21:
4 * Added new key command :StartTabbing (Mark)
5 Window.cc/hh CurrentWindowCmd.cc/hh
3*07/12/20: 6*07/12/20:
4 * Added new key command :ForEach (or :Map) (Mark) 7 * Added new key command :ForEach (or :Map) (Mark)
5 - :ForEach {<command>} [{ [{<list opts>}] [<bool command>] }] 8 - :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
30session.doubleClickInterval: 250 30session.doubleClickInterval: 250
31session.cacheMax: 200 31session.cacheMax: 200
32session.imageDither: True 32session.imageDither: True
33session.configVersion: 6 33session.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
15OnWindow Mod1 Mouse1 :StartMoving 15OnWindow Mod1 Mouse1 :StartMoving
16OnWindow Mod1 Mouse3 :StartResizing 16OnWindow Mod1 Mouse3 :StartResizing
17 17
18# middle click a window's titlebar and drag to attach windows
19OnTitlebar Mouse2 :StartTabbing
20
18# double click on the titlebar to shade 21# double click on the titlebar to shade
19OnTitlebar Double Mouse1 :Shade 22OnTitlebar Double Mouse1 :Shade
20 23
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() {
313 } 313 }
314} 314}
315 315
316REGISTER_OBJECT(starttabbing, StartTabbingCmd, Command);
317
318void StartTabbingCmd::real_execute() {
319 const XEvent &last = Fluxbox::instance()->lastEvent();
320 if (last.type == ButtonPress) {
321 const XButtonEvent &be = last.xbutton;
322 fbwindow().startTabbing(be);
323 }
324}
325
316FbTk::Command *MoveCmd::parse(const string &command, const string &args, 326FbTk::Command *MoveCmd::parse(const string &command, const string &args,
317 bool trusted) { 327 bool trusted) {
318 FbTk_istringstream is(args.c_str()); 328 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:
159 const FluxboxWindow::ResizeModel m_mode; 159 const FluxboxWindow::ResizeModel m_mode;
160}; 160};
161 161
162// begin tabbing with mouse
163class StartTabbingCmd: public WindowHelperCmd {
164public:
165 StartTabbingCmd() { }
166protected:
167 void real_execute();
168};
169
162// move cmd, relative position 170// move cmd, relative position
163class MoveCmd: public WindowHelperCmd { 171class MoveCmd: public WindowHelperCmd {
164public: 172public:
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) {
2611 me.window = frame().window().window(); 2611 me.window = frame().window().window();
2612 } 2612 }
2613 2613
2614 bool inside_titlebar = (frame().titlebar() == me.window 2614 bool inside_titlebar = frame().gripLeft().window() != me.window &&
2615 || frame().label() == me.window 2615 frame().gripRight().window() != me.window &&
2616 || frame().tabcontainer() == me.window 2616 frame().clientArea().window() != me.window &&
2617 || frame().handle() == me.window 2617 frame().window() != me.window;
2618 || frame().window() == me.window);
2619 2618
2620 if (Fluxbox::instance()->getIgnoreBorder() && m_attaching_tab == 0 2619 if (Fluxbox::instance()->getIgnoreBorder() && m_attaching_tab == 0
2621 && !(isMoving() || isResizing())) { 2620 && !(isMoving() || isResizing())) {
@@ -2650,24 +2649,8 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2650 return; 2649 return;
2651 } 2650 }
2652 2651
2653 WinClient *client = 0; 2652 if (moving || (me.state & Button1Mask) && functions.move &&
2654 if (!inside_titlebar) { 2653 inside_titlebar && !isResizing() && m_attaching_tab == 0) {
2655 // determine if we're in titlebar
2656 Client2ButtonMap::iterator it =
2657 find_if(m_labelbuttons.begin(),
2658 m_labelbuttons.end(),
2659 Compose(bind2nd(equal_to<Window>(), me.window),
2660 Compose(mem_fun(&TextButton::window),
2661 Select2nd<Client2ButtonMap::value_type>())));
2662 if (it != m_labelbuttons.end()) {
2663 inside_titlebar = true;
2664 client = (*it).first;
2665 }
2666 }
2667
2668 if ((me.state & Button1Mask) && functions.move &&
2669 inside_titlebar &&
2670 !isResizing()) {
2671 2654
2672 if (! isMoving()) { 2655 if (! isMoving()) {
2673 startMoving(me.x_root, me.y_root); 2656 startMoving(me.x_root, me.y_root);
@@ -2741,7 +2724,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2741 2724
2742 screen().showPosition(dx, dy); 2725 screen().showPosition(dx, dy);
2743 } // end if moving 2726 } // end if moving
2744 } else if (functions.resize && 2727 } else if (resizing || m_attaching_tab == 0 && functions.resize &&
2745 (((me.state & Button1Mask) && 2728 (((me.state & Button1Mask) &&
2746 (me.window == frame().gripRight() || 2729 (me.window == frame().gripRight() ||
2747 me.window == frame().gripLeft())) || 2730 me.window == frame().gripLeft())) ||
@@ -2833,61 +2816,25 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2833 screen().showGeometry(gx, gy); 2816 screen().showGeometry(gx, gy);
2834 } 2817 }
2835 } 2818 }
2836 } else if (functions.tabable && 2819 } else if (m_attaching_tab != 0) {
2837 (me.state & Button2Mask) && inside_titlebar && (client != 0 || m_attaching_tab != 0)) {
2838 // 2820 //
2839 // drag'n'drop code for tabs 2821 // drag'n'drop code for tabs
2840 // 2822 //
2841 FbTk::TextButton &active_button = *m_labelbuttons[(m_attaching_tab==0)?client:m_attaching_tab];
2842 2823
2843 if (m_attaching_tab == 0) { 2824 // we already grabed and started to drag'n'drop tab
2844 if (s_num_grabs > 0) 2825 // so we update drag'n'drop-rectangle
2845 return; 2826 int dx = me.x_root - m_button_grab_x, dy = me.y_root - m_button_grab_y;
2846 // start drag'n'drop for tab
2847 m_attaching_tab = client;
2848 grabPointer(me.window, False, ButtonMotionMask |
2849 ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
2850 None, frame(). theme().moveCursor(), CurrentTime);
2851 // relative position on button
2852 m_button_grab_x = me.x;
2853 m_button_grab_y = me.y;
2854 // last known root mouse position
2855 m_last_move_x = me.x_root - me.x;
2856 m_last_move_y = me.y_root - me.y;
2857 // hijack extra vars for initial grab location
2858 m_last_resize_x = me.x_root;
2859 m_last_resize_y = me.y_root;
2860
2861 Fluxbox::instance()->grab();
2862
2863 parent().drawRectangle(screen().rootTheme().opGC(),
2864 m_last_move_x, m_last_move_y,
2865 active_button.width(),
2866 active_button.height());
2867
2868 menu().hide();
2869 } else {
2870 // we already grabed and started to drag'n'drop tab
2871 // so we update drag'n'drop-rectangle
2872 int dx = me.x_root - m_button_grab_x, dy = me.y_root - m_button_grab_y;
2873
2874 //erase rectangle
2875 parent().drawRectangle(screen().rootTheme().opGC(),
2876 m_last_move_x, m_last_move_y,
2877 active_button.width(),
2878 active_button.height());
2879
2880
2881 // redraw rectangle at new pos
2882 m_last_move_x = dx;
2883 m_last_move_y = dy;
2884 parent().drawRectangle(screen().rootTheme().opGC(),
2885 m_last_move_x, m_last_move_y,
2886 active_button.width(),
2887 active_button.height());
2888 2827
2828 parent().drawRectangle(screen().rootTheme().opGC(),
2829 m_last_move_x, m_last_move_y,
2830 m_last_resize_w, m_last_resize_h);
2831 parent().drawRectangle(screen().rootTheme().opGC(),
2832 dx, dy,
2833 m_last_resize_w, m_last_resize_h);
2889 2834
2890 } 2835 // change remembered position of rectangle
2836 m_last_move_x = dx;
2837 m_last_move_y = dy;
2891 } 2838 }
2892 2839
2893} 2840}
@@ -3116,7 +3063,7 @@ void FluxboxWindow::startMoving(int x, int y) {
3116 Fluxbox *fluxbox = Fluxbox::instance(); 3063 Fluxbox *fluxbox = Fluxbox::instance();
3117 // grabbing (and masking) on the root window allows us to 3064 // grabbing (and masking) on the root window allows us to
3118 // freely map and unmap the window we're moving. 3065 // freely map and unmap the window we're moving.
3119 grabPointer(screen().rootWindow().window(), False, Button1MotionMask | 3066 grabPointer(screen().rootWindow().window(), False, ButtonMotionMask |
3120 ButtonReleaseMask, GrabModeAsync, GrabModeAsync, 3067 ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
3121 screen().rootWindow().window(), frame().theme().moveCursor(), CurrentTime); 3068 screen().rootWindow().window(), frame().theme().moveCursor(), CurrentTime);
3122 3069
@@ -3467,14 +3414,64 @@ void FluxboxWindow::stopResizing(bool interrupted) {
3467 ungrabPointer(CurrentTime); 3414 ungrabPointer(CurrentTime);
3468} 3415}
3469 3416
3417void FluxboxWindow::startTabbing(const XButtonEvent &be) {
3418
3419 if (s_num_grabs > 0)
3420 return;
3421
3422 m_attaching_tab = 0;
3423 // determine if we're in titlebar
3424 Client2ButtonMap::iterator it =
3425 find_if(m_labelbuttons.begin(),
3426 m_labelbuttons.end(),
3427 Compose(bind2nd(equal_to<Window>(), be.window),
3428 Compose(mem_fun(&TextButton::window),
3429 Select2nd<Client2ButtonMap::value_type>())));
3430 if (it != m_labelbuttons.end())
3431 m_attaching_tab = it->first;
3432
3433 // start drag'n'drop for tab
3434 grabPointer(be.window, False, ButtonMotionMask |
3435 ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
3436 None, frame().theme().moveCursor(), CurrentTime);
3437
3438 // relative position on the button
3439 m_button_grab_x = be.x;
3440 m_button_grab_y = be.y;
3441 // position of the button
3442 m_last_move_x = be.x_root - be.x;
3443 m_last_move_y = be.y_root - be.y;
3444 // hijack extra vars for initial grab location
3445 m_last_resize_x = be.x_root;
3446 m_last_resize_y = be.y_root;
3447
3448 Fluxbox::instance()->grab();
3449
3450 if (m_attaching_tab) {
3451 FbTk::TextButton &active_button = *m_labelbuttons[m_attaching_tab];
3452 m_last_resize_w = active_button.width();
3453 m_last_resize_h = active_button.height();
3454 } else {
3455 m_attaching_tab = m_client;
3456 unsigned int bw = 2*frame().window().borderWidth()-1;
3457 m_last_resize_w = frame().width() + bw;
3458 m_last_resize_h = frame().height() + bw;
3459 }
3460
3461 parent().drawRectangle(screen().rootTheme().opGC(),
3462 m_last_move_x, m_last_move_y,
3463 m_last_resize_w, m_last_resize_h);
3464
3465 menu().hide();
3466}
3467
3470void FluxboxWindow::attachTo(int x, int y, bool interrupted) { 3468void FluxboxWindow::attachTo(int x, int y, bool interrupted) {
3471 if (m_attaching_tab == 0) 3469 if (m_attaching_tab == 0)
3472 return; 3470 return;
3473 3471
3474 parent().drawRectangle(screen().rootTheme().opGC(), 3472 parent().drawRectangle(screen().rootTheme().opGC(),
3475 m_last_move_x, m_last_move_y, 3473 m_last_move_x, m_last_move_y,
3476 m_labelbuttons[m_attaching_tab]->width(), 3474 m_last_resize_w, m_last_resize_h);
3477 m_labelbuttons[m_attaching_tab]->height());
3478 3475
3479 ungrabPointer(CurrentTime); 3476 ungrabPointer(CurrentTime);
3480 3477
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:
393 ResizeDirection getResizeDirection(int x, int y, ResizeModel model); 393 ResizeDirection getResizeDirection(int x, int y, ResizeModel model);
394 /// stops the resizing 394 /// stops the resizing
395 void stopResizing(bool interrupted = false); 395 void stopResizing(bool interrupted = false);
396 /// starts tabbing
397 void startTabbing(const XButtonEvent &be);
396 398
397 /** 399 /**
398 @name accessors 400 @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() {
643 if (create_init) 643 if (create_init)
644 FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str()); 644 FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str());
645 645
646#define CONFIG_VERSION 6 646#define CONFIG_VERSION 7
647 FbTk::Resource<int> config_version(m_resourcemanager, 0, 647 FbTk::Resource<int> config_version(m_resourcemanager, 0,
648 "session.configVersion", "Session.ConfigVersion"); 648 "session.configVersion", "Session.ConfigVersion");
649 if (*config_version < CONFIG_VERSION) { 649 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) {
275 new_version = 6; 275 new_version = 6;
276 } 276 }
277 277
278 if (old_version < 7) { // added StartTabbing command
279 string whole_keyfile = read_file(keyfilename);
280 string new_keyfile = "";
281 // let's put our new keybindings first, so they're easy to find
282 new_keyfile += "# start tabbing windows together\n";
283 new_keyfile += "OnTitlebar Mouse2 :StartTabbing\n\n";
284 new_keyfile += whole_keyfile; // don't forget user's old keybindings
285
286 write_file(keyfilename, new_keyfile);
287
288 new_version = 7;
289 }
290
278 return new_version; 291 return new_version;
279} 292}
280 293