diff options
author | Thomas Lübking <thomas.luebking@gmail.com> | 2016-09-13 14:17:04 (GMT) |
---|---|---|
committer | Mathias Gumz <akira@fluxbox.org> | 2016-09-21 18:52:14 (GMT) |
commit | bc1ad61a7d6f10debc5781032e428f297a6b2fad (patch) | |
tree | 3039bbfaa0a963d81c5d840af9bb3aa5dc6b8dbe | |
parent | 2678060eae574f3ff0858cd7907feaeb3c1f43df (diff) | |
download | fluxbox-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
-rw-r--r-- | src/Window.cc | 48 |
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 | ||
275 | int FluxboxWindow::s_num_grabs = 0; | 275 | int FluxboxWindow::s_num_grabs = 0; |
276 | static int s_original_workspace = 0; | ||
276 | 277 | ||
277 | FluxboxWindow::FluxboxWindow(WinClient &client): | 278 | FluxboxWindow::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 | ||
2771 | void FluxboxWindow::enterNotifyEvent(XCrossingEvent &ev) { | 2756 | void 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); |