all repos — fluxbox @ 40d026ff99bab25b7aa52e8e6c413277eb27006b

custom fork of the fluxbox windowmanager

transient window fix
fluxgen fluxgen
commit

40d026ff99bab25b7aa52e8e6c413277eb27006b

parent

94e3fa88fcede0b0e20d39dd577c85d9321b415d

1 files changed, 57 insertions(+), 36 deletions(-)

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

@@ -163,11 +163,12 @@

/// 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 @@ win.layerItem().raise();

} // 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 @@ if ((*it)->fbwindow() && !(*it)->fbwindow()->isIconic())

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

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 @@ // magic to detect if moved by hints

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 @@ if (m_client->initial_state == WithdrawnState) {

return; } + + Fluxbox::instance()->saveWindowSearchGroup(frame().window().window(), this); /**************************************************/

@@ -515,7 +522,6 @@ decorations.maximize = decorations.handle =

functions.resize = functions.maximize = false; decorations.tab = false; //no tab for this window } - associateClientWindow(true, wattrib.x, wattrib.y, wattrib.width, wattrib.height);

@@ -525,6 +531,8 @@

// this window is managed, we are now allowed to modify actual state m_initialized = true; + + applyDecorations(true); grabButtons();

@@ -560,6 +568,8 @@ wattrib.width = 1;

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,11 +586,15 @@ m_client->transientFor()->fbwindow()->title()<<endl;

} #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;

@@ -633,7 +647,7 @@

/// 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 @@ frame().clientArea().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 @@ evm.add(*this, btn->window()); // we take care of button events for this

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

/// 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 @@ removeClient(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 @@ }

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

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

// 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 @@ Atom atom_return;

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 @@ // case MapRequest:

// 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::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 @@ WinClient &client = *old_attached;

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::restore(WinClient *client, bool remap) { - if (client->m_win != this) + if (client->fbwindow() != this) return; XChangeSaveSet(display, client->window(), SetModeDelete);