aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfluxgen <fluxgen>2005-04-29 02:49:24 (GMT)
committerfluxgen <fluxgen>2005-04-29 02:49:24 (GMT)
commit40d026ff99bab25b7aa52e8e6c413277eb27006b (patch)
treed267634bdbd509a3b12f1ea2db28103278095ba2
parent94e3fa88fcede0b0e20d39dd577c85d9321b415d (diff)
downloadfluxbox_pavel-40d026ff99bab25b7aa52e8e6c413277eb27006b.zip
fluxbox_pavel-40d026ff99bab25b7aa52e8e6c413277eb27006b.tar.bz2
transient window fix
-rw-r--r--src/Window.cc93
1 files changed, 57 insertions, 36 deletions
diff --git a/src/Window.cc b/src/Window.cc
index f72075a..e899300 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -163,11 +163,12 @@ WinClient *getRootTransientFor(WinClient *client) {
163 163
164/// raise window and do the same for each transient of the current window 164/// raise window and do the same for each transient of the current window
165void raiseFluxboxWindow(FluxboxWindow &win) { 165void raiseFluxboxWindow(FluxboxWindow &win) {
166 if (win.oplock) return; 166 if (win.oplock)
167 return;
168
167 win.oplock = true; 169 win.oplock = true;
168#ifdef DEBUG 170
169 cerr<<"raiseFluxboxWindow("<<win.title()<<")"<<endl; 171
170#endif // DEBUG
171 // we need to lock actual restacking so that raising above active transient 172 // we need to lock actual restacking so that raising above active transient
172 // won't do anything nasty 173 // won't do anything nasty
173 if (!win.winClient().transientList().empty()) 174 if (!win.winClient().transientList().empty())
@@ -179,6 +180,7 @@ void raiseFluxboxWindow(FluxboxWindow &win) {
179 } 180 }
180 181
181 // for each transient do raise 182 // for each transient do raise
183
182 WinClient::TransientList::const_iterator it = win.winClient().transientList().begin(); 184 WinClient::TransientList::const_iterator it = win.winClient().transientList().begin();
183 WinClient::TransientList::const_iterator it_end = win.winClient().transientList().end(); 185 WinClient::TransientList::const_iterator it_end = win.winClient().transientList().end();
184 for (; it != it_end; ++it) { 186 for (; it != it_end; ++it) {
@@ -186,18 +188,20 @@ void raiseFluxboxWindow(FluxboxWindow &win) {
186 // TODO: should we also check if it is the active client? 188 // TODO: should we also check if it is the active client?
187 raiseFluxboxWindow(*(*it)->fbwindow()); 189 raiseFluxboxWindow(*(*it)->fbwindow());
188 } 190 }
191
189 win.oplock = false; 192 win.oplock = false;
190 193
194
191 if (!win.winClient().transientList().empty()) 195 if (!win.winClient().transientList().empty())
192 win.screen().layerManager().unlock(); 196 win.screen().layerManager().unlock();
193#ifdef DEBUG 197
194 cerr<<"window("<<win.title()<<") transient size: "<<win.winClient().transientList().size()<<endl;
195#endif // DEBUG
196} 198}
197 199
198/// lower window and do the same for each transient it holds 200/// lower window and do the same for each transient it holds
199void lowerFluxboxWindow(FluxboxWindow &win) { 201void lowerFluxboxWindow(FluxboxWindow &win) {
200 if (win.oplock) return; 202 if (win.oplock)
203 return;
204
201 win.oplock = true; 205 win.oplock = true;
202 206
203 // we need to lock actual restacking so that raising above active transient 207 // we need to lock actual restacking so that raising above active transient
@@ -220,6 +224,7 @@ void lowerFluxboxWindow(FluxboxWindow &win) {
220 win.oplock = false; 224 win.oplock = false;
221 if (!win.winClient().transientList().empty()) 225 if (!win.winClient().transientList().empty())
222 win.screen().layerManager().unlock(); 226 win.screen().layerManager().unlock();
227
223} 228}
224 229
225/// raise window and do the same for each transient it holds 230/// raise window and do the same for each transient it holds
@@ -255,8 +260,8 @@ public:
255 explicit SetClientCmd(WinClient &client):m_client(client) { 260 explicit SetClientCmd(WinClient &client):m_client(client) {
256 } 261 }
257 void execute() { 262 void execute() {
258 if (m_client.m_win != 0) 263 if (m_client.fbwindow() != 0)
259 m_client.m_win->setCurrentClient(m_client); 264 m_client.fbwindow()->setCurrentClient(m_client);
260 } 265 }
261private: 266private:
262 WinClient &m_client; 267 WinClient &m_client;
@@ -386,7 +391,7 @@ void FluxboxWindow::init() {
386 m_old_pos_x = 0; 391 m_old_pos_x = 0;
387 392
388 assert(m_client); 393 assert(m_client);
389 m_client->m_win = this; 394 m_client->setFluxboxWindow(this);
390 m_client->setGroupLeftWindow(None); // nothing to the left. 395 m_client->setGroupLeftWindow(None); // nothing to the left.
391 396
392 // check for shape extension and whether the window is shaped 397 // check for shape extension and whether the window is shaped
@@ -492,6 +497,8 @@ void FluxboxWindow::init() {
492 return; 497 return;
493 } 498 }
494 499
500
501
495 Fluxbox::instance()->saveWindowSearchGroup(frame().window().window(), this); 502 Fluxbox::instance()->saveWindowSearchGroup(frame().window().window(), this);
496 503
497 /**************************************************/ 504 /**************************************************/
@@ -516,7 +523,6 @@ void FluxboxWindow::init() {
516 decorations.tab = false; //no tab for this window 523 decorations.tab = false; //no tab for this window
517 } 524 }
518 525
519
520 associateClientWindow(true, wattrib.x, wattrib.y, wattrib.width, wattrib.height); 526 associateClientWindow(true, wattrib.x, wattrib.y, wattrib.width, wattrib.height);
521 527
522 528
@@ -525,6 +531,8 @@ void FluxboxWindow::init() {
525 // this window is managed, we are now allowed to modify actual state 531 // this window is managed, we are now allowed to modify actual state
526 m_initialized = true; 532 m_initialized = true;
527 533
534
535
528 applyDecorations(true); 536 applyDecorations(true);
529 537
530 grabButtons(); 538 grabButtons();
@@ -560,6 +568,8 @@ void FluxboxWindow::init() {
560 if (wattrib.height <= 0) 568 if (wattrib.height <= 0)
561 wattrib.height = 1; 569 wattrib.height = 1;
562 570
571
572
563 // if we're a transient then we should be on the same layer as our parent 573 // if we're a transient then we should be on the same layer as our parent
564 if (m_client->isTransient() && 574 if (m_client->isTransient() &&
565 m_client->transientFor()->fbwindow() && 575 m_client->transientFor()->fbwindow() &&
@@ -576,12 +586,16 @@ void FluxboxWindow::init() {
576 } 586 }
577#endif // DEBUG 587#endif // DEBUG
578 588
589
579 if (!place_window) 590 if (!place_window)
580 moveResize(frame().x(), frame().y(), frame().width(), frame().height()); 591 moveResize(frame().x(), frame().y(), frame().width(), frame().height());
581 592
593
594
582 screen().getWorkspace(m_workspace_number)->addWindow(*this, place_window); 595 screen().getWorkspace(m_workspace_number)->addWindow(*this, place_window);
583 setWorkspace(m_workspace_number); 596 setWorkspace(m_workspace_number);
584 597
598
585 if (shaded) { // start shaded 599 if (shaded) { // start shaded
586 shaded = false; 600 shaded = false;
587 shade(); 601 shade();
@@ -633,7 +647,7 @@ void FluxboxWindow::shape() {
633/// attach a client to this window and destroy old window 647/// attach a client to this window and destroy old window
634void FluxboxWindow::attachClient(WinClient &client, int x, int y) { 648void FluxboxWindow::attachClient(WinClient &client, int x, int y) {
635 //!! TODO: check for isGroupable in client 649 //!! TODO: check for isGroupable in client
636 if (client.m_win == this) 650 if (client.fbwindow() == this)
637 return; 651 return;
638 652
639 menu().hide(); 653 menu().hide();
@@ -678,7 +692,7 @@ void FluxboxWindow::attachClient(WinClient &client, int x, int y) {
678 frame().clientArea().width(), 692 frame().clientArea().width(),
679 frame().clientArea().height()); 693 frame().clientArea().height());
680 694
681 (*client_it)->m_win = this; 695 (*client_it)->setFluxboxWindow(this);
682 // create a labelbutton for this client and 696 // create a labelbutton for this client and
683 // associate it with the pointer 697 // associate it with the pointer
684 FbTk::TextButton *btn = new FbTk::TextButton(frame().label(), 698 FbTk::TextButton *btn = new FbTk::TextButton(frame().label(),
@@ -736,7 +750,7 @@ void FluxboxWindow::attachClient(WinClient &client, int x, int y) {
736 750
737 if (&client == focused_win) 751 if (&client == focused_win)
738 was_focused = focused_win; 752 was_focused = focused_win;
739 client.m_win = this; 753 client.setFluxboxWindow(this);
740 754
741 client.saveBlackboxAttribs(m_blackbox_attrib); 755 client.saveBlackboxAttribs(m_blackbox_attrib);
742 m_clientlist.push_back(&client); 756 m_clientlist.push_back(&client);
@@ -764,7 +778,7 @@ void FluxboxWindow::attachClient(WinClient &client, int x, int y) {
764 778
765/// detach client from window and create a new window for it 779/// detach client from window and create a new window for it
766bool FluxboxWindow::detachClient(WinClient &client) { 780bool FluxboxWindow::detachClient(WinClient &client) {
767 if (client.m_win != this || numClients() <= 1) 781 if (client.fbwindow() != this || numClients() <= 1)
768 return false; 782 return false;
769 783
770 // I'm not sure how to do this bit better 784 // I'm not sure how to do this bit better
@@ -811,7 +825,7 @@ bool FluxboxWindow::detachClient(WinClient &client) {
811 825
812 // m_client must be valid as there should be at least one other window 826 // m_client must be valid as there should be at least one other window
813 // otherwise this wouldn't be here (refer numClients() <= 1 return) 827 // otherwise this wouldn't be here (refer numClients() <= 1 return)
814 client.m_win = screen().createWindow(client); 828 client.setFluxboxWindow(screen().createWindow(client));
815 m_client->raise(); 829 m_client->raise();
816 setInputFocus(); 830 setInputFocus();
817 return true; 831 return true;
@@ -826,7 +840,7 @@ void FluxboxWindow::detachCurrentClient() {
826 840
827/// removes client from client list, does not create new fluxboxwindow for it 841/// removes client from client list, does not create new fluxboxwindow for it
828bool FluxboxWindow::removeClient(WinClient &client) { 842bool FluxboxWindow::removeClient(WinClient &client) {
829 if (client.m_win != this || numClients() == 0) 843 if (client.fbwindow() != this || numClients() == 0)
830 return false; 844 return false;
831 845
832#ifdef DEBUG 846#ifdef DEBUG
@@ -1111,7 +1125,7 @@ void FluxboxWindow::updateClientLeftWindow() {
1111 1125
1112bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { 1126bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) {
1113 // make sure it's in our list 1127 // make sure it's in our list
1114 if (client.m_win != this) 1128 if (client.fbwindow() != this)
1115 return false; 1129 return false;
1116 1130
1117 m_client = &client; 1131 m_client = &client;
@@ -1870,7 +1884,7 @@ void FluxboxWindow::raise() {
1870 if (isIconic()) 1884 if (isIconic())
1871 deiconify(); 1885 deiconify();
1872#ifdef DEBUG 1886#ifdef DEBUG
1873 cerr<<"FluxboxWindow("<<title()<<")::raise()[layer="<<layerNum()<<""<<endl; 1887 cerr<<"FluxboxWindow("<<title()<<")::raise()[layer="<<layerNum()<<"]"<<endl;
1874#endif // DEBUG 1888#endif // DEBUG
1875 // get root window 1889 // get root window
1876 WinClient *client = getRootTransientFor(m_client); 1890 WinClient *client = getRootTransientFor(m_client);
@@ -1878,10 +1892,17 @@ void FluxboxWindow::raise() {
1878 // if we don't have any root window use this as root 1892 // if we don't have any root window use this as root
1879 if (client == 0) 1893 if (client == 0)
1880 client = m_client; 1894 client = m_client;
1881 1895 // if we have transient_for then we should put ourself last in
1882 // raise this window and every transient in it 1896 // transients list so we get raised last and thus gets above the other transients
1897 if (m_client->transientFor() && m_client != m_client->transientFor()->transientList().back()) {
1898 // remove and push back so this window gets raised last
1899 m_client->transientFor()->transientList().remove(m_client);
1900 m_client->transientFor()->transientList().push_back(m_client);
1901 }
1902 // raise this window and every transient in it with this one last
1883 if (client->fbwindow()) 1903 if (client->fbwindow())
1884 raiseFluxboxWindow(*client->fbwindow()); 1904 raiseFluxboxWindow(*client->fbwindow());
1905
1885} 1906}
1886 1907
1887void FluxboxWindow::lower() { 1908void FluxboxWindow::lower() {
@@ -2178,13 +2199,11 @@ bool FluxboxWindow::getState() {
2178 bool ret = false; 2199 bool ret = false;
2179 int foo; 2200 int foo;
2180 unsigned long *state, ulfoo, nitems; 2201 unsigned long *state, ulfoo, nitems;
2181 if ((XGetWindowProperty(display, m_client->window(), FbAtoms::instance()->getWMStateAtom(), 2202 if (!m_client->property(FbAtoms::instance()->getWMStateAtom(),
2182 0l, 2l, false, FbAtoms::instance()->getWMStateAtom(), 2203 0l, 2l, false, FbAtoms::instance()->getWMStateAtom(),
2183 &atom_return, &foo, &nitems, &ulfoo, 2204 &atom_return, &foo, &nitems, &ulfoo,
2184 (unsigned char **) &state) != Success) || 2205 (unsigned char **) &state) || !state)
2185 (! state)) {
2186 return false; 2206 return false;
2187 }
2188 2207
2189 if (nitems >= 1) { 2208 if (nitems >= 1) {
2190 m_current_state = static_cast<unsigned long>(state[0]); 2209 m_current_state = static_cast<unsigned long>(state[0]);
@@ -2342,15 +2361,17 @@ void FluxboxWindow::handleEvent(XEvent &event) {
2342 // mapRequestEvent(event.xmaprequest); 2361 // mapRequestEvent(event.xmaprequest);
2343 //break; 2362 //break;
2344 case PropertyNotify: { 2363 case PropertyNotify: {
2364
2345#ifdef DEBUG 2365#ifdef DEBUG
2346 char *atomname = XGetAtomName(display, event.xproperty.atom); 2366 char *atomname = XGetAtomName(display, event.xproperty.atom);
2347 cerr<<"PropertyNotify("<<title()<<"), property = "<<atomname<<endl; 2367 cerr<<"PropertyNotify("<<title()<<"), property = "<<atomname<<endl;
2348 XFree(atomname); 2368 if (atomname)
2369 XFree(atomname);
2349#endif // DEBUG 2370#endif // DEBUG
2350 WinClient *client = findClient(event.xproperty.window); 2371 WinClient *client = findClient(event.xproperty.window);
2351 if (client) { 2372 if (client)
2352 propertyNotifyEvent(*client, event.xproperty.atom); 2373 propertyNotifyEvent(*client, event.xproperty.atom);
2353 } 2374
2354 } 2375 }
2355 break; 2376 break;
2356 2377
@@ -2513,7 +2534,7 @@ void FluxboxWindow::unmapNotifyEvent(XUnmapEvent &ue) {
2513void FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent &de) { 2534void FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent &de) {
2514 if (de.window == m_client->window()) { 2535 if (de.window == m_client->window()) {
2515#ifdef DEBUG 2536#ifdef DEBUG
2516 cerr<<__FILE__<<"("<<__LINE__<<"): DestroyNotifyEvent this="<<this<<endl; 2537 cerr<<__FILE__<<"("<<__LINE__<<"): DestroyNotifyEvent this="<<this<<" title = "<<title()<<endl;
2517#endif // DEBUG 2538#endif // DEBUG
2518 if (numClients() == 1) 2539 if (numClients() == 1)
2519 hide(); 2540 hide();
@@ -3511,9 +3532,9 @@ void FluxboxWindow::attachTo(int x, int y, bool interrupted) {
3511 detachClient(*old_attached); 3532 detachClient(*old_attached);
3512 // move window by relative amount of mouse movement 3533 // move window by relative amount of mouse movement
3513 // since just detached, move relative to old location 3534 // since just detached, move relative to old location
3514 if (client.m_win != 0) { 3535 if (client.fbwindow() != 0) {
3515 client.m_win->move(frame().x() - m_last_resize_x + x, frame().y() - m_last_resize_y + y); 3536 client.fbwindow()->move(frame().x() - m_last_resize_x + x, frame().y() - m_last_resize_y + y);
3516 client.m_win->show(); 3537 client.fbwindow()->show();
3517 } 3538 }
3518 } else if(attach_to_win==this && attach_to_win->isTabable()) { 3539 } else if(attach_to_win==this && attach_to_win->isTabable()) {
3519 //reording of tabs within a frame 3540 //reording of tabs within a frame
@@ -3524,7 +3545,7 @@ void FluxboxWindow::attachTo(int x, int y, bool interrupted) {
3524} 3545}
3525 3546
3526void FluxboxWindow::restore(WinClient *client, bool remap) { 3547void FluxboxWindow::restore(WinClient *client, bool remap) {
3527 if (client->m_win != this) 3548 if (client->fbwindow() != this)
3528 return; 3549 return;
3529 3550
3530 XChangeSaveSet(display, client->window(), SetModeDelete); 3551 XChangeSaveSet(display, client->window(), SetModeDelete);