all repos — fluxbox @ 9e96f89dbe6ad5a8ace36128d50d1c6737968fa8

custom fork of the fluxbox windowmanager

drag and drop support for tabs
fluxgen fluxgen
commit

9e96f89dbe6ad5a8ace36128d50d1c6737968fa8

parent

86f3dc3b8cb7bb1130343456b35db05c8ac0f4a0

2 files changed, 123 insertions(+), 11 deletions(-)

jump to
M src/Window.ccsrc/Window.cc

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// 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("<<this<<")"<<endl; #endif // DEBUG - if (moving || resizing) { + if (moving || resizing || m_attaching_tab) { screen.hideGeometry(); XUngrabPointer(display, CurrentTime); }

@@ -266,21 +266,24 @@ while (!m_clientlist.empty()) {

detachClient(*m_clientlist.back()); } } - + Fluxbox::instance()->removeWindowSearch(m_frame.window().window()); #ifdef DEBUG cerr<<__FILE__<<"("<<__LINE__<<"): ~FluxboxWindow("<<this<<")"<<endl; #endif // DEBUG } -void FluxboxWindow::init() { +void FluxboxWindow::init() { + m_attaching_tab = 0; assert(m_client); //!! TODO init of client should be better // we don't want to duplicate code here and in attachClient m_clientlist.push_back(m_client); #ifdef DEBUG - cerr<<__FILE__<<": FluxboxWindow::init(this="<<this<<", client="<<hex<<m_client->window()<<dec<<")"<<endl; -#endif // DEBUG + cerr<<__FILE__<<": FluxboxWindow::init(this="<<this<<", client="<<hex<< + m_client->window()<<", frame = "<<m_frame.window().window()<<dec<<")"<<endl; + +#endif // DEBUG TextButton *btn = new TextButton(m_frame.label(), m_frame.theme().font(), m_client->title());

@@ -360,6 +363,8 @@ m_client->x = wattrib.x; m_client->y = wattrib.y;

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 @@ me.window = m_frame.window().window();

} 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 @@ Client2ButtonMap::iterator it_end = m_labelbuttons.end();

for (; it != it_end; ++it) { if ((*it).second->window() == me.window) { inside_titlebar = true; + client = (*it).first; break; } }

@@ -2336,6 +2344,74 @@ last_resize_h - 1 + 2 * m_frame.window().borderWidth());

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="<<this<<endl; + // start drag'n'drop for tab + m_attaching_tab = client; + + XGrabPointer(display, me.window, False, Button2MotionMask | + ButtonReleaseMask, GrabModeAsync, GrabModeAsync, + None, Fluxbox::instance()->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()); + + } }

@@ -2590,6 +2666,39 @@ last_resize_w,

last_resize_h); 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
M src/Window.hhsrc/Window.hh

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// 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 @@ void stopMoving();

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 @@

//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;