From feb7462e381b4015bc736e90da87dc7cc5711b1a Mon Sep 17 00:00:00 2001 From: rathnor Date: Wed, 24 Sep 2003 14:02:25 +0000 Subject: Fix updates to mwm_hints, and make configure request move and resize atomic --- ChangeLog | 5 +++ src/FbAtoms.cc | 4 +- src/FbAtoms.hh | 6 ++- src/FbWinFrame.cc | 85 +++++++++++++++++++++++------------------ src/FbWinFrame.hh | 9 ++++- src/WinClient.cc | 4 +- src/Window.cc | 112 +++++++++++++++++++++++++++--------------------------- src/Window.hh | 12 +++--- 8 files changed, 131 insertions(+), 106 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5f33641..19f5dfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,11 @@ (Format: Year/Month/Day) Changes for 0.9.6: *03/09/24: + * Fix updates to mwm_hints, and make configure request + move and resize atomic (Simon) + - fixes mplayer fullscreen window being moveable + - fixes focus loss when toggling mplayer fullscreen + FbWinFrame.hh/cc Window.hh/cc FbAtoms.hh/cc WinClient.cc * Fixed the "aterm"-bug (Henrik) Window.cc *03/09/23: diff --git a/src/FbAtoms.cc b/src/FbAtoms.cc index 0271a56..de8a9a8 100644 --- a/src/FbAtoms.cc +++ b/src/FbAtoms.cc @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: FbAtoms.cc,v 1.8 2003/05/13 11:47:29 fluxgen Exp $ +// $Id: FbAtoms.cc,v 1.9 2003/09/24 14:02:25 rathnor Exp $ #include "FbAtoms.hh" #include "App.hh" @@ -46,7 +46,6 @@ FbAtoms::~FbAtoms() { FbAtoms *FbAtoms::instance() { if (s_singleton == 0) throw string("Create one instance of FbAtoms first!"); - return s_singleton; } @@ -60,6 +59,7 @@ void FbAtoms::initAtoms() { xa_wm_change_state = XInternAtom(display, "WM_CHANGE_STATE", False); xa_wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); xa_wm_take_focus = XInternAtom(display, "WM_TAKE_FOCUS", False); + motif_wm_hints = XInternAtom(display, "_MOTIF_WM_HINTS", False); blackbox_hints = XInternAtom(display, "_BLACKBOX_HINTS", False); blackbox_attributes = XInternAtom(display, "_BLACKBOX_ATTRIBUTES", False); diff --git a/src/FbAtoms.hh b/src/FbAtoms.hh index 2b4898c..3af1f31 100644 --- a/src/FbAtoms.hh +++ b/src/FbAtoms.hh @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: FbAtoms.hh,v 1.10 2003/04/26 18:56:02 fluxgen Exp $ +// $Id: FbAtoms.hh,v 1.11 2003/09/24 14:02:25 rathnor Exp $ #ifndef FBATOMS_HH #define FBATOMS_HH @@ -34,7 +34,6 @@ public: static FbAtoms *instance(); - inline Atom getWMChangeStateAtom() const { return xa_wm_change_state; } inline Atom getWMStateAtom() const { return xa_wm_state; } inline Atom getWMDeleteAtom() const { return xa_wm_delete_window; } @@ -44,6 +43,7 @@ public: // this atom is for normal app->WM hints about decorations, stacking, // starting workspace etc... inline Atom getFluxboxHintsAtom() const { return blackbox_hints;} + inline Atom getMWMHintsAtom() const { return motif_wm_hints; } // these atoms are for normal app->WM interaction beyond the scope of the // ICCCM... @@ -78,6 +78,8 @@ private: // NETAttributes Atom blackbox_attributes, blackbox_change_attributes, blackbox_hints; + Atom motif_wm_hints; + // NETStructureMessages Atom blackbox_structure_messages, blackbox_notify_startup, blackbox_notify_window_add, blackbox_notify_window_del, diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc index 1781fcd..fb309b4 100644 --- a/src/FbWinFrame.cc +++ b/src/FbWinFrame.cc @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: FbWinFrame.cc,v 1.53 2003/09/16 13:11:41 rathnor Exp $ +// $Id: FbWinFrame.cc,v 1.54 2003/09/24 14:02:25 rathnor Exp $ #include "FbWinFrame.hh" @@ -163,53 +163,66 @@ void FbWinFrame::shade() { void FbWinFrame::move(int x, int y) { - // don't update unless we really changes position - if (x == window().x() && y == window().y()) - return; + moveResize(x, y, 0, 0, true, false); +} - window().move(x, y); - // update transparent only if we need to - if (theme().alpha() == 255) - return; +void FbWinFrame::resize(unsigned int width, unsigned int height) { + moveResize(0, 0, width, height, false, true); +} - // restart update timer - m_update_timer.start(); +// need an atomic moveresize where possible +void FbWinFrame::moveResizeForClient(int x, int y, unsigned int width, unsigned int height, bool move, bool resize) { + // total height for frame - /* + unsigned int total_height = height; - */ + if (resize) { + // having a titlebar = 1 extra border + titlebar height + if (m_use_titlebar) + total_height += m_titlebar.height() + m_titlebar.borderWidth(); + // having a handle = 1 extra border + handle height + if (m_use_handle) + total_height += m_handle.height() + m_handle.borderWidth(); + } + moveResize(x, y, width, total_height, move, resize); } -void FbWinFrame::resize(unsigned int width, unsigned int height) { - // update unshaded size if we're in shaded state and just resize width - if (m_shaded) { +void FbWinFrame::resizeForClient(unsigned int width, unsigned int height) { + moveResizeForClient(0, 0, width, height, false, true); +} + +void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int height, bool move, bool resize) { + if (move && x == window().x() && y == window().y()) + move = false; + + if (resize && width == FbWinFrame::width() && height == FbWinFrame::height()) + resize = false; + + if (!move && !resize) + return; + + if (resize && m_shaded) { + // update unshaded size if we're in shaded state and just resize width m_width_before_shade = width; m_height_before_shade = height; - m_window.resize(width, m_window.height()); + height = m_window.height(); + } + + if (move && resize) { + m_window.moveResize(x, y, width, height); + } else if (move) { + m_window.move(x, y); + // this stuff will be caught by reconfigure if resized + if (theme().alpha() != 255) { + // restart update timer + m_update_timer.start(); + } } else { m_window.resize(width, height); } - reconfigure(); -} - -void FbWinFrame::resizeForClient(unsigned int width, unsigned int height) { - // total height for frame - unsigned int total_height = height; - - // having a titlebar = 1 extra border + titlebar height - if (m_use_titlebar) - total_height += m_titlebar.height() + m_titlebar.borderWidth(); - // having a handle = 1 extra border + handle height - if (m_use_handle) - total_height += m_handle.height() + m_handle.borderWidth(); - resize(width, total_height); -} - -void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int height) { - move(x, y); - if (width != FbWinFrame::width() || height != FbWinFrame::height()) - resize(width, height); + if (resize) + reconfigure(); } void FbWinFrame::setFocus(bool newvalue) { diff --git a/src/FbWinFrame.hh b/src/FbWinFrame.hh index 23b004b..f57ce32 100644 --- a/src/FbWinFrame.hh +++ b/src/FbWinFrame.hh @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: FbWinFrame.hh,v 1.20 2003/09/14 10:32:31 fluxgen Exp $ +// $Id: FbWinFrame.hh,v 1.21 2003/09/24 14:02:25 rathnor Exp $ #ifndef FBWINFRAME_HH #define FBWINFRAME_HH @@ -80,7 +80,12 @@ public: void resize(unsigned int width, unsigned int height); /// resize client to specified size and resize frame to it void resizeForClient(unsigned int width, unsigned int height); - void moveResize(int x, int y, unsigned int width, unsigned int height); + + // for when there needs to be an atomic move+resize operation + void moveResizeForClient(int x, int y, unsigned int width, unsigned int height, bool move = true, bool resize = true); + + // can elect to ignore move or resize (mainly for use of move/resize individual functions + void moveResize(int x, int y, unsigned int width, unsigned int height, bool move = true, bool resize = true); /// set focus/unfocus style void setFocus(bool newvalue); diff --git a/src/WinClient.cc b/src/WinClient.cc index 1c7b249..614b7a4 100644 --- a/src/WinClient.cc +++ b/src/WinClient.cc @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: WinClient.cc,v 1.26 2003/09/21 13:24:27 rathnor Exp $ +// $Id: WinClient.cc,v 1.27 2003/09/24 14:02:25 rathnor Exp $ #include "WinClient.hh" @@ -356,12 +356,12 @@ void WinClient::updateMWMHints() { int format; Atom atom_return; unsigned long num = 0, len = 0; - Atom motif_wm_hints = XInternAtom(FbTk::App::instance()->display(), "_MOTIF_WM_HINTS", False); if (m_mwm_hint) { XFree(m_mwm_hint); m_mwm_hint = 0; } + Atom motif_wm_hints = FbAtoms::instance()->getMWMHintsAtom(); if (!(property(motif_wm_hints, 0, PropMwmHintsElements, false, diff --git a/src/Window.cc b/src/Window.cc index 5d2f600..f35c21e 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.cc,v 1.233 2003/09/24 11:33:40 fluxgen Exp $ +// $Id: Window.cc,v 1.234 2003/09/24 14:02:25 rathnor Exp $ #include "Window.hh" @@ -415,9 +415,9 @@ void FluxboxWindow::init() { decorations.close = false; if (m_client->getBlackboxHint() != 0) - getBlackboxHints(); + updateBlackboxHintsFromClient(*m_client); else - getMWMHints(); + updateMWMHintsFromClient(*m_client); //!! // fetch client size and placement @@ -498,8 +498,7 @@ void FluxboxWindow::init() { } - frame().move(wattrib.x, wattrib.y); - frame().resizeForClient(wattrib.width, wattrib.height); + frame().moveResizeForClient(wattrib.x, wattrib.y, wattrib.width, wattrib.height); // if we're a transient then we should be on the same layer as our parent if (m_client->isTransient() && @@ -907,8 +906,8 @@ bool FluxboxWindow::isGroupable() const { void FluxboxWindow::associateClientWindow() { m_client->setBorderWidth(0); - updateTitleFromClient(); - updateIconNameFromClient(); + updateTitleFromClient(*m_client); + updateIconNameFromClient(*m_client); frame().setClientWindow(*m_client); frame().resizeForClient(m_client->width(), m_client->height()); @@ -964,25 +963,24 @@ void FluxboxWindow::reconfigure() { } /// update current client title and title in our frame -void FluxboxWindow::updateTitleFromClient() { - m_client->updateTitle(); +void FluxboxWindow::updateTitleFromClient(WinClient &client) { + client.updateTitle(); // compare old title with new and see if we need to update // graphics - if (m_labelbuttons[m_client]->text() != m_client->title()) { - m_labelbuttons[m_client]->setText(m_client->title()); - m_labelbuttons[m_client]->clear(); // redraw text - m_labelbuttons[m_client]->updateTransparent(); + if (m_labelbuttons[&client]->text() != client.title()) { + m_labelbuttons[&client]->setText(client.title()); + m_labelbuttons[&client]->clear(); // redraw text + m_labelbuttons[&client]->updateTransparent(); } } /// update icon title from client -void FluxboxWindow::updateIconNameFromClient() { - m_client->updateIconTitle(); +void FluxboxWindow::updateIconNameFromClient(WinClient &client) { + client.updateIconTitle(); } - -void FluxboxWindow::getMWMHints() { - const WinClient::MwmHints *hint = m_client->getMwmHint(); +void FluxboxWindow::updateMWMHintsFromClient(WinClient &client) { + const WinClient::MwmHints *hint = client.getMwmHint(); if (!hint) return; @@ -1049,8 +1047,8 @@ void FluxboxWindow::updateFunctions() { setupWindow(); } -void FluxboxWindow::getBlackboxHints() { - const FluxboxWindow::BlackboxHints *hint = m_client->getBlackboxHint(); +void FluxboxWindow::updateBlackboxHintsFromClient(WinClient &client) { + const FluxboxWindow::BlackboxHints *hint = client.getBlackboxHint(); if (!hint) return; if (hint->flags & ATTRIB_SHADED) @@ -1912,10 +1910,12 @@ void FluxboxWindow::handleEvent(XEvent &event) { // case MapRequest: // mapRequestEvent(event.xmaprequest); //break; - case PropertyNotify: - if (event.xproperty.state != PropertyDelete) { - propertyNotifyEvent(event.xproperty.atom); + case PropertyNotify: { + WinClient *client = findClient(event.xproperty.window); + if (client) { + propertyNotifyEvent(*client, event.xproperty.atom); } + } break; default: @@ -2076,8 +2076,7 @@ void FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent &de) { } -void FluxboxWindow::propertyNotifyEvent(Atom atom) { - +void FluxboxWindow::propertyNotifyEvent(WinClient &client, Atom atom) { switch(atom) { case XA_WM_CLASS: case XA_WM_CLIENT_MACHINE: @@ -2085,31 +2084,28 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) { break; case XA_WM_TRANSIENT_FOR: { - // TODO: this property notify should be handled by winclient - // but for now we'll justhave to update all transient info - //bool was_transient = isTransient(); - for_each(clientList().begin(), clientList().end(), - mem_fun(&WinClient::updateTransientInfo)); - reconfigure(); - // TODO: this is broken whilst we don't know which client + bool was_transient = client.isTransient(); + client.updateTransientInfo(); // update our layer to be the same layer as our transient for - //if (isTransient() && isTransient() != was_transient) - // layerItem().setLayer(getTransientFor()->layerItem().getLayer()); + if (client.isTransient() && !was_transient + && client.transientFor()->fbwindow()) + layerItem().setLayer(client.transientFor()->fbwindow()->layerItem().getLayer()); } break; case XA_WM_HINTS: - m_client->updateWMHints(); + client.updateWMHints(); hintSig().notify(); // notify listeners break; case XA_WM_ICON_NAME: - updateIconNameFromClient(); + client.updateIconTitle(); + updateIconNameFromClient(client); updateIcon(); break; case XA_WM_NAME: - updateTitleFromClient(); + updateTitleFromClient(client); if (! iconic) screen().getWorkspace(m_workspace_number)->update(); @@ -2120,27 +2116,27 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) { break; case XA_WM_NORMAL_HINTS: { - m_client->updateWMNormalHints(); + client.updateWMNormalHints(); - if ((m_client->normal_hint_flags & PMinSize) && - (m_client->normal_hint_flags & PMaxSize)) { + if ((client.normal_hint_flags & PMinSize) && + (client.normal_hint_flags & PMaxSize)) { - if (m_client->max_width != 0 && m_client->max_width <= m_client->min_width && - m_client->max_height != 0 && m_client->max_height <= m_client->min_height) { + if (client.max_width != 0 && client.max_width <= client.min_width && + client.max_height != 0 && client.max_height <= client.min_height) { decorations.maximize = false; decorations.handle = false; functions.resize=false; functions.maximize=false; } else { // TODO: is broken while handled by FbW, needs to be in WinClient - if (! winClient().isTransient()) { + if (! client.isTransient()) { decorations.maximize = true; decorations.handle = true; functions.maximize = true; } functions.resize = true; } - + setupWindow(); } // save old values @@ -2159,13 +2155,16 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) { } default: - if (atom == FbAtoms::instance()->getWMProtocolsAtom()) { - m_client->updateWMProtocols(); - //!!TODO check this area - // reset window actions - setupWindow(); - - } + FbAtoms *fbatoms = FbAtoms::instance(); + if (atom == fbatoms->getWMProtocolsAtom()) { + client.updateWMProtocols(); + } else if (atom == fbatoms->getMWMHintsAtom()) { + client.updateMWMHints(); + updateMWMHintsFromClient(client); + } else if (atom == fbatoms->getFluxboxHintsAtom()) { + client.updateBlackboxHints(); + updateBlackboxHintsFromClient(client); + } break; } @@ -2208,11 +2207,12 @@ void FluxboxWindow::configureRequestEvent(XConfigureRequestEvent &cr) { // the request is for client window so we resize the frame to it first if (frame().width() != cw || frame().height() != ch) { - frame().resizeForClient(cw, ch); + if (frame().x() != cx || frame().y() != cy) + frame().moveResizeForClient(cx, cy, cw, ch); + else + frame().resizeForClient(cw, ch); send_notify = true; - } - - if (frame().x() != cx || frame().y() != cy) { + } else if (frame().x() != cx || frame().y() != cy) { move(cx, cy); // since we already send a notify in move we don't need to do that again send_notify = false; @@ -2627,7 +2627,7 @@ void FluxboxWindow::applyDecorations(bool initial) { // if the location changes, shift it if (grav_x != 0 || grav_y != 0) - frame().move(grav_x + frame().x(), grav_y + frame().y()); + move(grav_x + frame().x(), grav_y + frame().y()); frame().reconfigure(); } diff --git a/src/Window.hh b/src/Window.hh index a07bf66..8c2fe46 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.hh,v 1.94 2003/09/23 13:52:05 rathnor Exp $ +// $Id: Window.hh,v 1.95 2003/09/24 14:02:25 rathnor Exp $ #ifndef WINDOW_HH #define WINDOW_HH @@ -236,7 +236,7 @@ public: void unmapNotifyEvent(XUnmapEvent &unmapev); void exposeEvent(XExposeEvent &ee); void configureRequestEvent(XConfigureRequestEvent &ce); - void propertyNotifyEvent(Atom a); + void propertyNotifyEvent(WinClient &client, Atom a); void enterNotifyEvent(XCrossingEvent &ev); void leaveNotifyEvent(XCrossingEvent &ev); //@} @@ -374,11 +374,11 @@ private: bool getState(); /// gets title string from client window and updates frame's title - void updateTitleFromClient(); + void updateTitleFromClient(WinClient &client); /// gets icon name from client window - void updateIconNameFromClient(); - void getMWMHints(); - void getBlackboxHints(); + void updateIconNameFromClient(WinClient &client); + void updateMWMHintsFromClient(WinClient &client); + void updateBlackboxHintsFromClient(WinClient &client); void saveBlackboxAttribs(); void setNetWMAttributes(); void associateClientWindow(); -- cgit v0.11.2