aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfluxgen <fluxgen>2003-04-15 14:40:24 (GMT)
committerfluxgen <fluxgen>2003-04-15 14:40:24 (GMT)
commit9e96f89dbe6ad5a8ace36128d50d1c6737968fa8 (patch)
treed4e3420d3e070bd06667af40b2aa7e6e2ea9b312 /src
parent86f3dc3b8cb7bb1130343456b35db05c8ac0f4a0 (diff)
downloadfluxbox-9e96f89dbe6ad5a8ace36128d50d1c6737968fa8.zip
fluxbox-9e96f89dbe6ad5a8ace36128d50d1c6737968fa8.tar.bz2
drag and drop support for tabs
Diffstat (limited to 'src')
-rw-r--r--src/Window.cc127
-rw-r--r--src/Window.hh7
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 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Window.cc,v 1.134 2003/04/15 12:31:53 fluxgen Exp $ 25// $Id: Window.cc,v 1.135 2003/04/15 14:40:24 fluxgen Exp $
26 26
27#include "Window.hh" 27#include "Window.hh"
28 28
@@ -238,7 +238,7 @@ FluxboxWindow::~FluxboxWindow() {
238#ifdef DEBUG 238#ifdef DEBUG
239 cerr<<__FILE__<<"("<<__LINE__<<"): starting ~FluxboxWindow("<<this<<")"<<endl; 239 cerr<<__FILE__<<"("<<__LINE__<<"): starting ~FluxboxWindow("<<this<<")"<<endl;
240#endif // DEBUG 240#endif // DEBUG
241 if (moving || resizing) { 241 if (moving || resizing || m_attaching_tab) {
242 screen.hideGeometry(); 242 screen.hideGeometry();
243 XUngrabPointer(display, CurrentTime); 243 XUngrabPointer(display, CurrentTime);
244 } 244 }
@@ -266,21 +266,24 @@ FluxboxWindow::~FluxboxWindow() {
266 detachClient(*m_clientlist.back()); 266 detachClient(*m_clientlist.back());
267 } 267 }
268 } 268 }
269 269 Fluxbox::instance()->removeWindowSearch(m_frame.window().window());
270#ifdef DEBUG 270#ifdef DEBUG
271 cerr<<__FILE__<<"("<<__LINE__<<"): ~FluxboxWindow("<<this<<")"<<endl; 271 cerr<<__FILE__<<"("<<__LINE__<<"): ~FluxboxWindow("<<this<<")"<<endl;
272#endif // DEBUG 272#endif // DEBUG
273} 273}
274 274
275 275
276void FluxboxWindow::init() { 276void FluxboxWindow::init() {
277 m_attaching_tab = 0;
277 assert(m_client); 278 assert(m_client);
278 //!! TODO init of client should be better 279 //!! TODO init of client should be better
279 // we don't want to duplicate code here and in attachClient 280 // we don't want to duplicate code here and in attachClient
280 m_clientlist.push_back(m_client); 281 m_clientlist.push_back(m_client);
281#ifdef DEBUG 282#ifdef DEBUG
282 cerr<<__FILE__<<": FluxboxWindow::init(this="<<this<<", client="<<hex<<m_client->window()<<dec<<")"<<endl; 283 cerr<<__FILE__<<": FluxboxWindow::init(this="<<this<<", client="<<hex<<
283#endif // DEBUG 284 m_client->window()<<", frame = "<<m_frame.window().window()<<dec<<")"<<endl;
285
286#endif // DEBUG
284 TextButton *btn = new TextButton(m_frame.label(), 287 TextButton *btn = new TextButton(m_frame.label(),
285 m_frame.theme().font(), 288 m_frame.theme().font(),
286 m_client->title()); 289 m_client->title());
@@ -361,6 +364,8 @@ void FluxboxWindow::init() {
361 364
362 Fluxbox *fluxbox = Fluxbox::instance(); 365 Fluxbox *fluxbox = Fluxbox::instance();
363 366
367 fluxbox->saveWindowSearch(m_frame.window().window(), this);
368
364 timer.setTimeout(fluxbox->getAutoRaiseDelay()); 369 timer.setTimeout(fluxbox->getAutoRaiseDelay());
365 timer.fireOnce(true); 370 timer.fireOnce(true);
366 371
@@ -2187,15 +2192,17 @@ void FluxboxWindow::shapeEvent(XShapeEvent *) { }
2187 2192
2188void FluxboxWindow::buttonReleaseEvent(XButtonEvent &re) { 2193void FluxboxWindow::buttonReleaseEvent(XButtonEvent &re) {
2189 2194
2190
2191 if (isMoving()) 2195 if (isMoving())
2192 stopMoving(); 2196 stopMoving();
2193 else if (isResizing()) 2197 else if (isResizing())
2194 stopResizing(); 2198 stopResizing();
2199 else if (m_attaching_tab)
2200 attachTo(re.x_root, re.y_root);
2195 else if (re.window == m_frame.window()) { 2201 else if (re.window == m_frame.window()) {
2196 if (re.button == 2 && re.state == Mod1Mask) 2202 if (re.button == 2 && re.state == Mod1Mask)
2197 XUngrabPointer(display, CurrentTime); 2203 XUngrabPointer(display, CurrentTime);
2198 m_frame.buttonReleaseEvent(re); 2204 else
2205 m_frame.buttonReleaseEvent(re);
2199 } else { 2206 } else {
2200 m_frame.buttonReleaseEvent(re); 2207 m_frame.buttonReleaseEvent(re);
2201 } 2208 }
@@ -2208,7 +2215,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2208 } 2215 }
2209 bool inside_titlebar = (m_frame.titlebar() == me.window || m_frame.label() == me.window || 2216 bool inside_titlebar = (m_frame.titlebar() == me.window || m_frame.label() == me.window ||
2210 m_frame.handle() == me.window || m_frame.window() == me.window); 2217 m_frame.handle() == me.window || m_frame.window() == me.window);
2211 2218 WinClient *client = 0;
2212 if (!inside_titlebar) { 2219 if (!inside_titlebar) {
2213 // determine if we're in titlebar 2220 // determine if we're in titlebar
2214 Client2ButtonMap::iterator it = m_labelbuttons.begin(); 2221 Client2ButtonMap::iterator it = m_labelbuttons.begin();
@@ -2216,6 +2223,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2216 for (; it != it_end; ++it) { 2223 for (; it != it_end; ++it) {
2217 if ((*it).second->window() == me.window) { 2224 if ((*it).second->window() == me.window) {
2218 inside_titlebar = true; 2225 inside_titlebar = true;
2226 client = (*it).first;
2219 break; 2227 break;
2220 } 2228 }
2221 } 2229 }
@@ -2337,6 +2345,74 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2337 if (screen.doShowWindowPos()) 2345 if (screen.doShowWindowPos())
2338 screen.showGeometry(gx, gy); 2346 screen.showGeometry(gx, gy);
2339 } 2347 }
2348 } else if ((me.state & Button2Mask) && inside_titlebar && client != 0) {
2349
2350 //
2351 // drag'n'drop code for tabs
2352 //
2353 if (m_attaching_tab == 0) {
2354 cerr<<"starting m_attching_tab for this="<<this<<endl;
2355 // start drag'n'drop for tab
2356 m_attaching_tab = client;
2357
2358 XGrabPointer(display, me.window, False, Button2MotionMask |
2359 ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
2360 None, Fluxbox::instance()->getMoveCursor(), CurrentTime);
2361 last_move_x = me.x_root - 1;
2362 last_move_y = me.y_root - 1;
2363
2364 XDrawRectangle(display, getScreen().getRootWindow(),
2365 getScreen().getOpGC(),
2366 last_move_x, last_move_y,
2367 m_labelbuttons[client]->width(),
2368 m_labelbuttons[client]->height());
2369 } else {
2370 // we already grabed and started to drag'n'drop tab
2371 // so we update drag'n'drop-rectangle
2372 int dx = me.x_root - 1, dy = me.y_root - 1;
2373
2374 dx -= getScreen().getBorderWidth();
2375 dy -= getScreen().getBorderWidth();
2376
2377 if (getScreen().getEdgeSnapThreshold()) {
2378 int drx = getScreen().getWidth() - (dx + 1);
2379
2380 if (dx > 0 && dx < drx && dx < getScreen().getEdgeSnapThreshold())
2381 dx = 0;
2382 else if (drx > 0 && drx < getScreen().getEdgeSnapThreshold())
2383 dx = getScreen().getWidth() - 1;
2384
2385 int dty, dby;
2386
2387 dty = dy;
2388 dby = -dy - 1;
2389
2390 if (dy > 0 && dty < getScreen().getEdgeSnapThreshold())
2391 dy = 0;
2392 else if (dby > 0 && dby < getScreen().getEdgeSnapThreshold())
2393 dy = - 1;
2394
2395 }
2396
2397 //erase rectangle
2398 XDrawRectangle(display, getScreen().getRootWindow(),
2399 getScreen().getOpGC(),
2400 last_move_x, last_move_y,
2401 m_labelbuttons[client]->width(),
2402 m_labelbuttons[client]->height());
2403
2404
2405 //redraw rectangle at new pos
2406 last_move_x = dx;
2407 last_move_y = dy;
2408 XDrawRectangle(display, getScreen().getRootWindow(),
2409 getScreen().getOpGC(),
2410 last_move_x, last_move_y,
2411 m_labelbuttons[client]->width(),
2412 m_labelbuttons[client]->height());
2413
2414
2415 }
2340 } 2416 }
2341 2417
2342} 2418}
@@ -2592,6 +2668,39 @@ void FluxboxWindow::stopResizing(Window win) {
2592 XUngrabPointer(display, CurrentTime); 2668 XUngrabPointer(display, CurrentTime);
2593} 2669}
2594 2670
2671void FluxboxWindow::attachTo(int x, int y) {
2672 if (m_attaching_tab == 0)
2673 return;
2674
2675 XUngrabPointer(display, CurrentTime);
2676
2677
2678 XDrawRectangle(display, getScreen().getRootWindow(),
2679 getScreen().getOpGC(),
2680 last_move_x, last_move_y,
2681 m_labelbuttons[m_attaching_tab]->width(),
2682 m_labelbuttons[m_attaching_tab]->height());
2683
2684 int dest_x = 0, dest_y = 0;
2685 Window child = 0;
2686
2687 if (XTranslateCoordinates(display, getScreen().getRootWindow(),
2688 getScreen().getRootWindow(),
2689 x, y, &dest_x, &dest_y, &child)) {
2690 // search for a fluxboxwindow
2691 FluxboxWindow *attach_to_win = Fluxbox::instance()->searchWindow(child);
2692
2693 if (attach_to_win != this &&
2694 attach_to_win != 0) {
2695 attach_to_win->attachClient(*m_attaching_tab);
2696 } else if (attach_to_win != this) { // disconnect client if we didn't drop on a window
2697 detachClient(*m_attaching_tab);
2698 }
2699
2700 }
2701 m_attaching_tab = 0;
2702}
2703
2595//finds and redraw the icon label 2704//finds and redraw the icon label
2596void FluxboxWindow::updateIcon() { 2705void FluxboxWindow::updateIcon() {
2597 if (Fluxbox::instance()->useIconBar()) { 2706 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 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Window.hh,v 1.54 2003/04/14 14:45:14 fluxgen Exp $ 25// $Id: Window.hh,v 1.55 2003/04/15 14:39:15 fluxgen Exp $
26 26
27#ifndef WINDOW_HH 27#ifndef WINDOW_HH
28#define WINDOW_HH 28#define WINDOW_HH
@@ -318,7 +318,9 @@ private:
318 void startResizing(Window win, int x, int y, bool left); 318 void startResizing(Window win, int x, int y, bool left);
319 void stopResizing(Window win=0); 319 void stopResizing(Window win=0);
320 void updateIcon(); 320 void updateIcon();
321 321 /// try to attach current attaching client to a window at pos x, y
322 void attachTo(int x, int y);
323
322 void updateTransientInfo(); 324 void updateTransientInfo();
323 325
324 bool getState(); 326 bool getState();
@@ -355,6 +357,7 @@ private:
355 //Window state 357 //Window state
356 bool moving, resizing, shaded, maximized, visible, iconic, transient, 358 bool moving, resizing, shaded, maximized, visible, iconic, transient,
357 focused, stuck, modal, send_focus_message, m_managed; 359 focused, stuck, modal, send_focus_message, m_managed;
360 WinClient *m_attaching_tab;
358 361
359 BScreen &screen; /// screen on which this window exist 362 BScreen &screen; /// screen on which this window exist
360 FbTk::Timer timer; 363 FbTk::Timer timer;