From 9e96f89dbe6ad5a8ace36128d50d1c6737968fa8 Mon Sep 17 00:00:00 2001 From: fluxgen Date: Tue, 15 Apr 2003 14:40:24 +0000 Subject: drag and drop support for tabs --- src/Window.cc | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- src/Window.hh | 7 +++- 2 files changed, 123 insertions(+), 11 deletions(-) diff --git a/src/Window.cc b/src/Window.cc index e207af3..ec82bd5 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.cc,v 1.134 2003/04/15 12:31:53 fluxgen Exp $ +// $Id: Window.cc,v 1.135 2003/04/15 14:40:24 fluxgen Exp $ #include "Window.hh" @@ -238,7 +238,7 @@ FluxboxWindow::~FluxboxWindow() { #ifdef DEBUG cerr<<__FILE__<<"("<<__LINE__<<"): starting ~FluxboxWindow("<removeWindowSearch(m_frame.window().window()); #ifdef DEBUG cerr<<__FILE__<<"("<<__LINE__<<"): ~FluxboxWindow("<title()); @@ -361,6 +364,8 @@ void FluxboxWindow::init() { Fluxbox *fluxbox = Fluxbox::instance(); + fluxbox->saveWindowSearch(m_frame.window().window(), this); + timer.setTimeout(fluxbox->getAutoRaiseDelay()); timer.fireOnce(true); @@ -2187,15 +2192,17 @@ void FluxboxWindow::shapeEvent(XShapeEvent *) { } void FluxboxWindow::buttonReleaseEvent(XButtonEvent &re) { - if (isMoving()) stopMoving(); else if (isResizing()) stopResizing(); + else if (m_attaching_tab) + attachTo(re.x_root, re.y_root); else if (re.window == m_frame.window()) { if (re.button == 2 && re.state == Mod1Mask) XUngrabPointer(display, CurrentTime); - m_frame.buttonReleaseEvent(re); + else + m_frame.buttonReleaseEvent(re); } else { m_frame.buttonReleaseEvent(re); } @@ -2208,7 +2215,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { } bool inside_titlebar = (m_frame.titlebar() == me.window || m_frame.label() == me.window || m_frame.handle() == me.window || m_frame.window() == me.window); - + WinClient *client = 0; if (!inside_titlebar) { // determine if we're in titlebar Client2ButtonMap::iterator it = m_labelbuttons.begin(); @@ -2216,6 +2223,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { for (; it != it_end; ++it) { if ((*it).second->window() == me.window) { inside_titlebar = true; + client = (*it).first; break; } } @@ -2337,6 +2345,74 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { if (screen.doShowWindowPos()) screen.showGeometry(gx, gy); } + } else if ((me.state & Button2Mask) && inside_titlebar && client != 0) { + + // + // drag'n'drop code for tabs + // + if (m_attaching_tab == 0) { + cerr<<"starting m_attching_tab for this="<getMoveCursor(), CurrentTime); + last_move_x = me.x_root - 1; + last_move_y = me.y_root - 1; + + XDrawRectangle(display, getScreen().getRootWindow(), + getScreen().getOpGC(), + last_move_x, last_move_y, + m_labelbuttons[client]->width(), + m_labelbuttons[client]->height()); + } else { + // we already grabed and started to drag'n'drop tab + // so we update drag'n'drop-rectangle + int dx = me.x_root - 1, dy = me.y_root - 1; + + dx -= getScreen().getBorderWidth(); + dy -= getScreen().getBorderWidth(); + + if (getScreen().getEdgeSnapThreshold()) { + int drx = getScreen().getWidth() - (dx + 1); + + if (dx > 0 && dx < drx && dx < getScreen().getEdgeSnapThreshold()) + dx = 0; + else if (drx > 0 && drx < getScreen().getEdgeSnapThreshold()) + dx = getScreen().getWidth() - 1; + + int dty, dby; + + dty = dy; + dby = -dy - 1; + + if (dy > 0 && dty < getScreen().getEdgeSnapThreshold()) + dy = 0; + else if (dby > 0 && dby < getScreen().getEdgeSnapThreshold()) + dy = - 1; + + } + + //erase rectangle + XDrawRectangle(display, getScreen().getRootWindow(), + getScreen().getOpGC(), + last_move_x, last_move_y, + m_labelbuttons[client]->width(), + m_labelbuttons[client]->height()); + + + //redraw rectangle at new pos + last_move_x = dx; + last_move_y = dy; + XDrawRectangle(display, getScreen().getRootWindow(), + getScreen().getOpGC(), + last_move_x, last_move_y, + m_labelbuttons[client]->width(), + m_labelbuttons[client]->height()); + + + } } } @@ -2592,6 +2668,39 @@ void FluxboxWindow::stopResizing(Window win) { XUngrabPointer(display, CurrentTime); } +void FluxboxWindow::attachTo(int x, int y) { + if (m_attaching_tab == 0) + return; + + XUngrabPointer(display, CurrentTime); + + + XDrawRectangle(display, getScreen().getRootWindow(), + getScreen().getOpGC(), + last_move_x, last_move_y, + m_labelbuttons[m_attaching_tab]->width(), + m_labelbuttons[m_attaching_tab]->height()); + + int dest_x = 0, dest_y = 0; + Window child = 0; + + if (XTranslateCoordinates(display, getScreen().getRootWindow(), + getScreen().getRootWindow(), + x, y, &dest_x, &dest_y, &child)) { + // search for a fluxboxwindow + FluxboxWindow *attach_to_win = Fluxbox::instance()->searchWindow(child); + + if (attach_to_win != this && + attach_to_win != 0) { + attach_to_win->attachClient(*m_attaching_tab); + } else if (attach_to_win != this) { // disconnect client if we didn't drop on a window + detachClient(*m_attaching_tab); + } + + } + m_attaching_tab = 0; +} + //finds and redraw the icon label void FluxboxWindow::updateIcon() { if (Fluxbox::instance()->useIconBar()) { diff --git a/src/Window.hh b/src/Window.hh index e8e4641..c246e9f 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.hh,v 1.54 2003/04/14 14:45:14 fluxgen Exp $ +// $Id: Window.hh,v 1.55 2003/04/15 14:39:15 fluxgen Exp $ #ifndef WINDOW_HH #define WINDOW_HH @@ -318,7 +318,9 @@ private: void startResizing(Window win, int x, int y, bool left); void stopResizing(Window win=0); void updateIcon(); - + /// try to attach current attaching client to a window at pos x, y + void attachTo(int x, int y); + void updateTransientInfo(); bool getState(); @@ -355,6 +357,7 @@ private: //Window state bool moving, resizing, shaded, maximized, visible, iconic, transient, focused, stuck, modal, send_focus_message, m_managed; + WinClient *m_attaching_tab; BScreen &screen; /// screen on which this window exist FbTk::Timer timer; -- cgit v0.11.2