aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lübking <thomas.luebking@gmail.com>2016-09-13 14:17:04 (GMT)
committerMathias Gumz <akira@fluxbox.org>2016-09-21 18:52:14 (GMT)
commitbc1ad61a7d6f10debc5781032e428f297a6b2fad (patch)
tree3039bbfaa0a963d81c5d840af9bb3aa5dc6b8dbe /src
parent2678060eae574f3ff0858cd7907feaeb3c1f43df (diff)
downloadfluxbox-bc1ad61a7d6f10debc5781032e428f297a6b2fad.zip
fluxbox-bc1ad61a7d6f10debc5781032e428f297a6b2fad.tar.bz2
allow to drag tabs to other workspaces
We simply re-use the move code. The major pitfall is that we must not unmap the dragged window, since it holds a pointer grab (which will break by unmapping it, so we fail to continue or finish the tab drag) Instead, the window is always send to the current workspace and if detached, all other clients in the group are send back to their original desktop. REQUEST: 234
Diffstat (limited to 'src')
-rw-r--r--src/Window.cc48
1 files changed, 16 insertions, 32 deletions
diff --git a/src/Window.cc b/src/Window.cc
index 1e15dc8..5eaf0d5 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -273,6 +273,7 @@ WinButton* makeButton(FluxboxWindow& win, FocusableTheme<WinButtonTheme>& btheme
273 273
274 274
275int FluxboxWindow::s_num_grabs = 0; 275int FluxboxWindow::s_num_grabs = 0;
276static int s_original_workspace = 0;
276 277
277FluxboxWindow::FluxboxWindow(WinClient &client): 278FluxboxWindow::FluxboxWindow(WinClient &client):
278 Focusable(client.screen(), this), 279 Focusable(client.screen(), this),
@@ -2518,7 +2519,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2518 e.xmotion.y = me.y_root; 2519 e.xmotion.y = me.y_root;
2519 } 2520 }
2520 2521
2521 if (moving) { 2522 if (moving || m_attaching_tab) {
2522 2523
2523 XEvent e; 2524 XEvent e;
2524 2525
@@ -2527,6 +2528,8 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2527 return; 2528 return;
2528 } 2529 }
2529 2530
2531 const bool xor_outline = m_attaching_tab || !screen().doOpaqueMove();
2532
2530 // Warp to next or previous workspace?, must have moved sideways some 2533 // Warp to next or previous workspace?, must have moved sideways some
2531 int moved_x = me.x_root - m_last_resize_x; 2534 int moved_x = me.x_root - m_last_resize_x;
2532 // save last event point 2535 // save last event point
@@ -2534,7 +2537,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2534 m_last_resize_y = me.y_root; 2537 m_last_resize_y = me.y_root;
2535 2538
2536 // undraw rectangle before warping workspaces 2539 // undraw rectangle before warping workspaces
2537 if (!screen().doOpaqueMove()) { 2540 if (xor_outline) {
2538 int bw = static_cast<int>(frame().window().borderWidth()); 2541 int bw = static_cast<int>(frame().window().borderWidth());
2539 int w = static_cast<int>(frame().width()) + 2*bw -1; 2542 int w = static_cast<int>(frame().width()) + 2*bw -1;
2540 int h = static_cast<int>(frame().height()) + 2*bw - 1; 2543 int h = static_cast<int>(frame().height()) + 2*bw - 1;
@@ -2573,7 +2576,8 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2573 XWarpPointer(display, None, me.root, 0, 0, 0, 0, 2576 XWarpPointer(display, None, me.root, 0, 0, 0, 0,
2574 m_last_resize_x, m_last_resize_y); 2577 m_last_resize_x, m_last_resize_y);
2575 2578
2576 if (screen().doOpaqueMove()) 2579 if (m_attaching_tab || // tabbing grabs the pointer, we must not hide the window!
2580 screen().doOpaqueMove())
2577 screen().sendToWorkspace(new_id, this, true); 2581 screen().sendToWorkspace(new_id, this, true);
2578 else 2582 else
2579 screen().changeWorkspaceID(new_id, false); 2583 screen().changeWorkspaceID(new_id, false);
@@ -2587,11 +2591,12 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2587 dy -= frame().window().borderWidth(); 2591 dy -= frame().window().borderWidth();
2588 2592
2589 // dx = current left side, dy = current top 2593 // dx = current left side, dy = current top
2590 doSnapping(dx, dy); 2594 if (moving)
2595 doSnapping(dx, dy);
2591 2596
2592 // do not update display if another motion event is already pending 2597 // do not update display if another motion event is already pending
2593 2598
2594 if (!screen().doOpaqueMove()) { 2599 if (xor_outline) {
2595 int bw = frame().window().borderWidth(); 2600 int bw = frame().window().borderWidth();
2596 int w = static_cast<int>(frame().width()) + 2*bw - 1; 2601 int w = static_cast<int>(frame().width()) + 2*bw - 1;
2597 int h = static_cast<int>(frame().height()) + 2*bw - 1; 2602 int h = static_cast<int>(frame().height()) + 2*bw - 1;
@@ -2605,8 +2610,8 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2605 // need to move the base window without interfering with transparency 2610 // need to move the base window without interfering with transparency
2606 frame().quietMoveResize(dx, dy, frame().width(), frame().height()); 2611 frame().quietMoveResize(dx, dy, frame().width(), frame().height());
2607 } 2612 }
2608 2613 if (moving)
2609 screen().showPosition(dx, dy); 2614 screen().showPosition(dx, dy);
2610 // end if moving 2615 // end if moving
2611 } else if (resizing) { 2616 } else if (resizing) {
2612 2617
@@ -2745,27 +2750,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2745 m_last_resize_h - 1 + 2 * frame().window().borderWidth()); 2750 m_last_resize_h - 1 + 2 * frame().window().borderWidth());
2746 2751
2747 } 2752 }
2748 } else if (m_attaching_tab != 0) {
2749 //
2750 // drag'n'drop code for tabs
2751 //
2752
2753 // we already grabed and started to drag'n'drop tab
2754 // so we update drag'n'drop-rectangle
2755 int dx = me.x_root - m_button_grab_x, dy = me.y_root - m_button_grab_y;
2756
2757 parent().drawRectangle(screen().rootTheme()->opGC(),
2758 m_last_move_x, m_last_move_y,
2759 m_last_resize_w, m_last_resize_h);
2760 parent().drawRectangle(screen().rootTheme()->opGC(),
2761 dx, dy,
2762 m_last_resize_w, m_last_resize_h);
2763
2764 // change remembered position of rectangle
2765 m_last_move_x = dx;
2766 m_last_move_y = dy;
2767 } 2753 }
2768
2769} 2754}
2770 2755
2771void FluxboxWindow::enterNotifyEvent(XCrossingEvent &ev) { 2756void FluxboxWindow::enterNotifyEvent(XCrossingEvent &ev) {
@@ -3335,6 +3320,7 @@ void FluxboxWindow::startTabbing(const XButtonEvent &be) {
3335 if (s_num_grabs > 0) 3320 if (s_num_grabs > 0)
3336 return; 3321 return;
3337 3322
3323 s_original_workspace = workspaceNumber();
3338 m_attaching_tab = winClientOfLabelButtonWindow(be.window); 3324 m_attaching_tab = winClientOfLabelButtonWindow(be.window);
3339 3325
3340 // start drag'n'drop for tab 3326 // start drag'n'drop for tab
@@ -3423,11 +3409,9 @@ void FluxboxWindow::attachTo(int x, int y, bool interrupted) {
3423 // disconnect client if we didn't drop on a window 3409 // disconnect client if we didn't drop on a window
3424 WinClient &client = *old_attached; 3410 WinClient &client = *old_attached;
3425 detachClient(*old_attached); 3411 detachClient(*old_attached);
3426 // move window by relative amount of mouse movement 3412 screen().sendToWorkspace(s_original_workspace, this, false);
3427 // since just detached, move relative to old location 3413 if (FluxboxWindow *fbwin = client.fbwindow())
3428 if (client.fbwindow() != 0) { 3414 fbwin->move(m_last_move_x, m_last_move_y);
3429 client.fbwindow()->move(frame().x() - m_last_resize_x + x, frame().y() - m_last_resize_y + y);
3430 }
3431 } else if( attach_to_win == this && attach_to_win->isTabable()) { 3415 } else if( attach_to_win == this && attach_to_win->isTabable()) {
3432 //reording of tabs within a frame 3416 //reording of tabs within a frame
3433 moveClientTo(*old_attached, x, y); 3417 moveClientTo(*old_attached, x, y);