From 40d026ff99bab25b7aa52e8e6c413277eb27006b Mon Sep 17 00:00:00 2001 From: fluxgen <fluxgen> Date: Fri, 29 Apr 2005 02:49:24 +0000 Subject: transient window fix --- src/Window.cc | 93 ++++++++++++++++++++++++++++++++++++----------------------- 1 file 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) { /// raise window and do the same for each transient of the current window void raiseFluxboxWindow(FluxboxWindow &win) { - if (win.oplock) return; + if (win.oplock) + return; + win.oplock = true; -#ifdef DEBUG - cerr<<"raiseFluxboxWindow("<<win.title()<<")"<<endl; -#endif // DEBUG + + // we need to lock actual restacking so that raising above active transient // won't do anything nasty if (!win.winClient().transientList().empty()) @@ -179,6 +180,7 @@ void raiseFluxboxWindow(FluxboxWindow &win) { } // for each transient do raise + WinClient::TransientList::const_iterator it = win.winClient().transientList().begin(); WinClient::TransientList::const_iterator it_end = win.winClient().transientList().end(); for (; it != it_end; ++it) { @@ -186,18 +188,20 @@ void raiseFluxboxWindow(FluxboxWindow &win) { // TODO: should we also check if it is the active client? raiseFluxboxWindow(*(*it)->fbwindow()); } + win.oplock = false; + if (!win.winClient().transientList().empty()) win.screen().layerManager().unlock(); -#ifdef DEBUG - cerr<<"window("<<win.title()<<") transient size: "<<win.winClient().transientList().size()<<endl; -#endif // DEBUG + } /// lower window and do the same for each transient it holds void lowerFluxboxWindow(FluxboxWindow &win) { - if (win.oplock) return; + if (win.oplock) + return; + win.oplock = true; // we need to lock actual restacking so that raising above active transient @@ -220,6 +224,7 @@ void lowerFluxboxWindow(FluxboxWindow &win) { win.oplock = false; if (!win.winClient().transientList().empty()) win.screen().layerManager().unlock(); + } /// raise window and do the same for each transient it holds @@ -255,8 +260,8 @@ public: explicit SetClientCmd(WinClient &client):m_client(client) { } void execute() { - if (m_client.m_win != 0) - m_client.m_win->setCurrentClient(m_client); + if (m_client.fbwindow() != 0) + m_client.fbwindow()->setCurrentClient(m_client); } private: WinClient &m_client; @@ -386,7 +391,7 @@ void FluxboxWindow::init() { m_old_pos_x = 0; assert(m_client); - m_client->m_win = this; + m_client->setFluxboxWindow(this); m_client->setGroupLeftWindow(None); // nothing to the left. // check for shape extension and whether the window is shaped @@ -492,6 +497,8 @@ void FluxboxWindow::init() { return; } + + Fluxbox::instance()->saveWindowSearchGroup(frame().window().window(), this); /**************************************************/ @@ -516,7 +523,6 @@ void FluxboxWindow::init() { decorations.tab = false; //no tab for this window } - associateClientWindow(true, wattrib.x, wattrib.y, wattrib.width, wattrib.height); @@ -525,6 +531,8 @@ void FluxboxWindow::init() { // this window is managed, we are now allowed to modify actual state m_initialized = true; + + applyDecorations(true); grabButtons(); @@ -560,6 +568,8 @@ void FluxboxWindow::init() { if (wattrib.height <= 0) wattrib.height = 1; + + // if we're a transient then we should be on the same layer as our parent if (m_client->isTransient() && m_client->transientFor()->fbwindow() && @@ -576,12 +586,16 @@ void FluxboxWindow::init() { } #endif // DEBUG + if (!place_window) moveResize(frame().x(), frame().y(), frame().width(), frame().height()); + + screen().getWorkspace(m_workspace_number)->addWindow(*this, place_window); setWorkspace(m_workspace_number); + if (shaded) { // start shaded shaded = false; shade(); @@ -633,7 +647,7 @@ void FluxboxWindow::shape() { /// attach a client to this window and destroy old window void FluxboxWindow::attachClient(WinClient &client, int x, int y) { //!! TODO: check for isGroupable in client - if (client.m_win == this) + if (client.fbwindow() == this) return; menu().hide(); @@ -678,7 +692,7 @@ void FluxboxWindow::attachClient(WinClient &client, int x, int y) { frame().clientArea().width(), frame().clientArea().height()); - (*client_it)->m_win = this; + (*client_it)->setFluxboxWindow(this); // create a labelbutton for this client and // associate it with the pointer FbTk::TextButton *btn = new FbTk::TextButton(frame().label(), @@ -736,7 +750,7 @@ void FluxboxWindow::attachClient(WinClient &client, int x, int y) { if (&client == focused_win) was_focused = focused_win; - client.m_win = this; + client.setFluxboxWindow(this); client.saveBlackboxAttribs(m_blackbox_attrib); m_clientlist.push_back(&client); @@ -764,7 +778,7 @@ void FluxboxWindow::attachClient(WinClient &client, int x, int y) { /// detach client from window and create a new window for it bool FluxboxWindow::detachClient(WinClient &client) { - if (client.m_win != this || numClients() <= 1) + if (client.fbwindow() != this || numClients() <= 1) return false; // I'm not sure how to do this bit better @@ -811,7 +825,7 @@ bool FluxboxWindow::detachClient(WinClient &client) { // m_client must be valid as there should be at least one other window // otherwise this wouldn't be here (refer numClients() <= 1 return) - client.m_win = screen().createWindow(client); + client.setFluxboxWindow(screen().createWindow(client)); m_client->raise(); setInputFocus(); return true; @@ -826,7 +840,7 @@ void FluxboxWindow::detachCurrentClient() { /// removes client from client list, does not create new fluxboxwindow for it bool FluxboxWindow::removeClient(WinClient &client) { - if (client.m_win != this || numClients() == 0) + if (client.fbwindow() != this || numClients() == 0) return false; #ifdef DEBUG @@ -1111,7 +1125,7 @@ void FluxboxWindow::updateClientLeftWindow() { bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { // make sure it's in our list - if (client.m_win != this) + if (client.fbwindow() != this) return false; m_client = &client; @@ -1870,7 +1884,7 @@ void FluxboxWindow::raise() { if (isIconic()) deiconify(); #ifdef DEBUG - cerr<<"FluxboxWindow("<<title()<<")::raise()[layer="<<layerNum()<<""<<endl; + cerr<<"FluxboxWindow("<<title()<<")::raise()[layer="<<layerNum()<<"]"<<endl; #endif // DEBUG // get root window WinClient *client = getRootTransientFor(m_client); @@ -1878,10 +1892,17 @@ void FluxboxWindow::raise() { // if we don't have any root window use this as root if (client == 0) client = m_client; - - // raise this window and every transient in it + // if we have transient_for then we should put ourself last in + // transients list so we get raised last and thus gets above the other transients + if (m_client->transientFor() && m_client != m_client->transientFor()->transientList().back()) { + // remove and push back so this window gets raised last + m_client->transientFor()->transientList().remove(m_client); + m_client->transientFor()->transientList().push_back(m_client); + } + // raise this window and every transient in it with this one last if (client->fbwindow()) raiseFluxboxWindow(*client->fbwindow()); + } void FluxboxWindow::lower() { @@ -2178,13 +2199,11 @@ bool FluxboxWindow::getState() { bool ret = false; int foo; unsigned long *state, ulfoo, nitems; - if ((XGetWindowProperty(display, m_client->window(), FbAtoms::instance()->getWMStateAtom(), - 0l, 2l, false, FbAtoms::instance()->getWMStateAtom(), - &atom_return, &foo, &nitems, &ulfoo, - (unsigned char **) &state) != Success) || - (! state)) { + if (!m_client->property(FbAtoms::instance()->getWMStateAtom(), + 0l, 2l, false, FbAtoms::instance()->getWMStateAtom(), + &atom_return, &foo, &nitems, &ulfoo, + (unsigned char **) &state) || !state) return false; - } if (nitems >= 1) { m_current_state = static_cast<unsigned long>(state[0]); @@ -2342,15 +2361,17 @@ void FluxboxWindow::handleEvent(XEvent &event) { // mapRequestEvent(event.xmaprequest); //break; case PropertyNotify: { + #ifdef DEBUG char *atomname = XGetAtomName(display, event.xproperty.atom); cerr<<"PropertyNotify("<<title()<<"), property = "<<atomname<<endl; - XFree(atomname); + if (atomname) + XFree(atomname); #endif // DEBUG WinClient *client = findClient(event.xproperty.window); - if (client) { + if (client) propertyNotifyEvent(*client, event.xproperty.atom); - } + } break; @@ -2513,7 +2534,7 @@ void FluxboxWindow::unmapNotifyEvent(XUnmapEvent &ue) { void FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent &de) { if (de.window == m_client->window()) { #ifdef DEBUG - cerr<<__FILE__<<"("<<__LINE__<<"): DestroyNotifyEvent this="<<this<<endl; + cerr<<__FILE__<<"("<<__LINE__<<"): DestroyNotifyEvent this="<<this<<" title = "<<title()<<endl; #endif // DEBUG if (numClients() == 1) hide(); @@ -3511,9 +3532,9 @@ void FluxboxWindow::attachTo(int x, int y, bool interrupted) { detachClient(*old_attached); // move window by relative amount of mouse movement // since just detached, move relative to old location - if (client.m_win != 0) { - client.m_win->move(frame().x() - m_last_resize_x + x, frame().y() - m_last_resize_y + y); - client.m_win->show(); + if (client.fbwindow() != 0) { + client.fbwindow()->move(frame().x() - m_last_resize_x + x, frame().y() - m_last_resize_y + y); + client.fbwindow()->show(); } } else if(attach_to_win==this && attach_to_win->isTabable()) { //reording of tabs within a frame @@ -3524,7 +3545,7 @@ void FluxboxWindow::attachTo(int x, int y, bool interrupted) { } void FluxboxWindow::restore(WinClient *client, bool remap) { - if (client->m_win != this) + if (client->fbwindow() != this) return; XChangeSaveSet(display, client->window(), SetModeDelete); -- cgit v0.11.2