diff options
author | fluxgen <fluxgen> | 2005-04-29 02:49:24 (GMT) |
---|---|---|
committer | fluxgen <fluxgen> | 2005-04-29 02:49:24 (GMT) |
commit | 40d026ff99bab25b7aa52e8e6c413277eb27006b (patch) | |
tree | d267634bdbd509a3b12f1ea2db28103278095ba2 /src/Window.cc | |
parent | 94e3fa88fcede0b0e20d39dd577c85d9321b415d (diff) | |
download | fluxbox_pavel-40d026ff99bab25b7aa52e8e6c413277eb27006b.zip fluxbox_pavel-40d026ff99bab25b7aa52e8e6c413277eb27006b.tar.bz2 |
transient window fix
Diffstat (limited to 'src/Window.cc')
-rw-r--r-- | src/Window.cc | 93 |
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 |
165 | void raiseFluxboxWindow(FluxboxWindow &win) { | 165 | void 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 |
199 | void lowerFluxboxWindow(FluxboxWindow &win) { | 201 | void 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 | } |
261 | private: | 266 | private: |
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 |
634 | void FluxboxWindow::attachClient(WinClient &client, int x, int y) { | 648 | void 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 |
766 | bool FluxboxWindow::detachClient(WinClient &client) { | 780 | bool 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 |
828 | bool FluxboxWindow::removeClient(WinClient &client) { | 842 | bool 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 | ||
1112 | bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { | 1126 | bool 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 | ||
1887 | void FluxboxWindow::lower() { | 1908 | void 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) { | |||
2513 | void FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent &de) { | 2534 | void 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 | ||
3526 | void FluxboxWindow::restore(WinClient *client, bool remap) { | 3547 | void 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); |