Fix updates to mwm_hints, and make configure request move and resize atomic

This commit is contained in:
rathnor 2003-09-24 14:02:25 +00:00
parent bec4f7c894
commit feb7462e38
8 changed files with 134 additions and 109 deletions

View file

@ -1,6 +1,11 @@
(Format: Year/Month/Day) (Format: Year/Month/Day)
Changes for 0.9.6: Changes for 0.9.6:
*03/09/24: *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) * Fixed the "aterm"-bug (Henrik)
Window.cc Window.cc
*03/09/23: *03/09/23:

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // 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 "FbAtoms.hh"
#include "App.hh" #include "App.hh"
@ -46,7 +46,6 @@ FbAtoms::~FbAtoms() {
FbAtoms *FbAtoms::instance() { FbAtoms *FbAtoms::instance() {
if (s_singleton == 0) if (s_singleton == 0)
throw string("Create one instance of FbAtoms first!"); throw string("Create one instance of FbAtoms first!");
return s_singleton; return s_singleton;
} }
@ -60,6 +59,7 @@ void FbAtoms::initAtoms() {
xa_wm_change_state = XInternAtom(display, "WM_CHANGE_STATE", False); xa_wm_change_state = XInternAtom(display, "WM_CHANGE_STATE", False);
xa_wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); xa_wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
xa_wm_take_focus = XInternAtom(display, "WM_TAKE_FOCUS", 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_hints = XInternAtom(display, "_BLACKBOX_HINTS", False);
blackbox_attributes = XInternAtom(display, "_BLACKBOX_ATTRIBUTES", False); blackbox_attributes = XInternAtom(display, "_BLACKBOX_ATTRIBUTES", False);

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // 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 #ifndef FBATOMS_HH
#define FBATOMS_HH #define FBATOMS_HH
@ -34,7 +34,6 @@ public:
static FbAtoms *instance(); static FbAtoms *instance();
inline Atom getWMChangeStateAtom() const { return xa_wm_change_state; } inline Atom getWMChangeStateAtom() const { return xa_wm_change_state; }
inline Atom getWMStateAtom() const { return xa_wm_state; } inline Atom getWMStateAtom() const { return xa_wm_state; }
inline Atom getWMDeleteAtom() const { return xa_wm_delete_window; } 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, // this atom is for normal app->WM hints about decorations, stacking,
// starting workspace etc... // starting workspace etc...
inline Atom getFluxboxHintsAtom() const { return blackbox_hints;} 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 // these atoms are for normal app->WM interaction beyond the scope of the
// ICCCM... // ICCCM...
@ -78,6 +78,8 @@ private:
// NETAttributes // NETAttributes
Atom blackbox_attributes, blackbox_change_attributes, blackbox_hints; Atom blackbox_attributes, blackbox_change_attributes, blackbox_hints;
Atom motif_wm_hints;
// NETStructureMessages // NETStructureMessages
Atom blackbox_structure_messages, blackbox_notify_startup, Atom blackbox_structure_messages, blackbox_notify_startup,
blackbox_notify_window_add, blackbox_notify_window_del, blackbox_notify_window_add, blackbox_notify_window_del,

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // 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" #include "FbWinFrame.hh"
@ -163,53 +163,66 @@ void FbWinFrame::shade() {
void FbWinFrame::move(int x, int y) { void FbWinFrame::move(int x, int y) {
// don't update unless we really changes position moveResize(x, y, 0, 0, true, false);
if (x == window().x() && y == window().y())
return;
window().move(x, y);
// update transparent only if we need to
if (theme().alpha() == 255)
return;
// restart update timer
m_update_timer.start();
/*
*/
} }
void FbWinFrame::resize(unsigned int width, unsigned int height) { void FbWinFrame::resize(unsigned int width, unsigned int height) {
// update unshaded size if we're in shaded state and just resize width moveResize(0, 0, width, height, false, true);
if (m_shaded) { }
// 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::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_width_before_shade = width;
m_height_before_shade = height; 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 { } else {
m_window.resize(width, height); m_window.resize(width, height);
} }
reconfigure(); if (resize)
} 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);
} }
void FbWinFrame::setFocus(bool newvalue) { void FbWinFrame::setFocus(bool newvalue) {

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // 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 #ifndef FBWINFRAME_HH
#define FBWINFRAME_HH #define FBWINFRAME_HH
@ -80,7 +80,12 @@ public:
void resize(unsigned int width, unsigned int height); void resize(unsigned int width, unsigned int height);
/// resize client to specified size and resize frame to it /// resize client to specified size and resize frame to it
void resizeForClient(unsigned int width, unsigned int height); 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 /// set focus/unfocus style
void setFocus(bool newvalue); void setFocus(bool newvalue);

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // 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" #include "WinClient.hh"
@ -356,12 +356,12 @@ void WinClient::updateMWMHints() {
int format; int format;
Atom atom_return; Atom atom_return;
unsigned long num = 0, len = 0; unsigned long num = 0, len = 0;
Atom motif_wm_hints = XInternAtom(FbTk::App::instance()->display(), "_MOTIF_WM_HINTS", False);
if (m_mwm_hint) { if (m_mwm_hint) {
XFree(m_mwm_hint); XFree(m_mwm_hint);
m_mwm_hint = 0; m_mwm_hint = 0;
} }
Atom motif_wm_hints = FbAtoms::instance()->getMWMHintsAtom();
if (!(property(motif_wm_hints, 0, if (!(property(motif_wm_hints, 0,
PropMwmHintsElements, false, PropMwmHintsElements, false,

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // 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" #include "Window.hh"
@ -415,9 +415,9 @@ void FluxboxWindow::init() {
decorations.close = false; decorations.close = false;
if (m_client->getBlackboxHint() != 0) if (m_client->getBlackboxHint() != 0)
getBlackboxHints(); updateBlackboxHintsFromClient(*m_client);
else else
getMWMHints(); updateMWMHintsFromClient(*m_client);
//!! //!!
// fetch client size and placement // fetch client size and placement
@ -498,8 +498,7 @@ void FluxboxWindow::init() {
} }
frame().move(wattrib.x, wattrib.y); frame().moveResizeForClient(wattrib.x, wattrib.y, wattrib.width, wattrib.height);
frame().resizeForClient(wattrib.width, wattrib.height);
// if we're a transient then we should be on the same layer as our parent // if we're a transient then we should be on the same layer as our parent
if (m_client->isTransient() && if (m_client->isTransient() &&
@ -907,8 +906,8 @@ bool FluxboxWindow::isGroupable() const {
void FluxboxWindow::associateClientWindow() { void FluxboxWindow::associateClientWindow() {
m_client->setBorderWidth(0); m_client->setBorderWidth(0);
updateTitleFromClient(); updateTitleFromClient(*m_client);
updateIconNameFromClient(); updateIconNameFromClient(*m_client);
frame().setClientWindow(*m_client); frame().setClientWindow(*m_client);
frame().resizeForClient(m_client->width(), m_client->height()); frame().resizeForClient(m_client->width(), m_client->height());
@ -964,25 +963,24 @@ void FluxboxWindow::reconfigure() {
} }
/// update current client title and title in our frame /// update current client title and title in our frame
void FluxboxWindow::updateTitleFromClient() { void FluxboxWindow::updateTitleFromClient(WinClient &client) {
m_client->updateTitle(); client.updateTitle();
// compare old title with new and see if we need to update // compare old title with new and see if we need to update
// graphics // graphics
if (m_labelbuttons[m_client]->text() != m_client->title()) { if (m_labelbuttons[&client]->text() != client.title()) {
m_labelbuttons[m_client]->setText(m_client->title()); m_labelbuttons[&client]->setText(client.title());
m_labelbuttons[m_client]->clear(); // redraw text m_labelbuttons[&client]->clear(); // redraw text
m_labelbuttons[m_client]->updateTransparent(); m_labelbuttons[&client]->updateTransparent();
} }
} }
/// update icon title from client /// update icon title from client
void FluxboxWindow::updateIconNameFromClient() { void FluxboxWindow::updateIconNameFromClient(WinClient &client) {
m_client->updateIconTitle(); client.updateIconTitle();
} }
void FluxboxWindow::updateMWMHintsFromClient(WinClient &client) {
void FluxboxWindow::getMWMHints() { const WinClient::MwmHints *hint = client.getMwmHint();
const WinClient::MwmHints *hint = m_client->getMwmHint();
if (!hint) return; if (!hint) return;
@ -1049,8 +1047,8 @@ void FluxboxWindow::updateFunctions() {
setupWindow(); setupWindow();
} }
void FluxboxWindow::getBlackboxHints() { void FluxboxWindow::updateBlackboxHintsFromClient(WinClient &client) {
const FluxboxWindow::BlackboxHints *hint = m_client->getBlackboxHint(); const FluxboxWindow::BlackboxHints *hint = client.getBlackboxHint();
if (!hint) return; if (!hint) return;
if (hint->flags & ATTRIB_SHADED) if (hint->flags & ATTRIB_SHADED)
@ -1912,10 +1910,12 @@ void FluxboxWindow::handleEvent(XEvent &event) {
// case MapRequest: // case MapRequest:
// mapRequestEvent(event.xmaprequest); // mapRequestEvent(event.xmaprequest);
//break; //break;
case PropertyNotify: case PropertyNotify: {
if (event.xproperty.state != PropertyDelete) { WinClient *client = findClient(event.xproperty.window);
propertyNotifyEvent(event.xproperty.atom); if (client) {
propertyNotifyEvent(*client, event.xproperty.atom);
} }
}
break; break;
default: default:
@ -2076,8 +2076,7 @@ void FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent &de) {
} }
void FluxboxWindow::propertyNotifyEvent(Atom atom) { void FluxboxWindow::propertyNotifyEvent(WinClient &client, Atom atom) {
switch(atom) { switch(atom) {
case XA_WM_CLASS: case XA_WM_CLASS:
case XA_WM_CLIENT_MACHINE: case XA_WM_CLIENT_MACHINE:
@ -2085,31 +2084,28 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) {
break; break;
case XA_WM_TRANSIENT_FOR: { case XA_WM_TRANSIENT_FOR: {
// TODO: this property notify should be handled by winclient bool was_transient = client.isTransient();
// but for now we'll justhave to update all transient info client.updateTransientInfo();
//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
// update our layer to be the same layer as our transient for // update our layer to be the same layer as our transient for
//if (isTransient() && isTransient() != was_transient) if (client.isTransient() && !was_transient
// layerItem().setLayer(getTransientFor()->layerItem().getLayer()); && client.transientFor()->fbwindow())
layerItem().setLayer(client.transientFor()->fbwindow()->layerItem().getLayer());
} break; } break;
case XA_WM_HINTS: case XA_WM_HINTS:
m_client->updateWMHints(); client.updateWMHints();
hintSig().notify(); // notify listeners hintSig().notify(); // notify listeners
break; break;
case XA_WM_ICON_NAME: case XA_WM_ICON_NAME:
updateIconNameFromClient(); client.updateIconTitle();
updateIconNameFromClient(client);
updateIcon(); updateIcon();
break; break;
case XA_WM_NAME: case XA_WM_NAME:
updateTitleFromClient(); updateTitleFromClient(client);
if (! iconic) if (! iconic)
screen().getWorkspace(m_workspace_number)->update(); screen().getWorkspace(m_workspace_number)->update();
@ -2120,27 +2116,27 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) {
break; break;
case XA_WM_NORMAL_HINTS: { case XA_WM_NORMAL_HINTS: {
m_client->updateWMNormalHints(); client.updateWMNormalHints();
if ((m_client->normal_hint_flags & PMinSize) && if ((client.normal_hint_flags & PMinSize) &&
(m_client->normal_hint_flags & PMaxSize)) { (client.normal_hint_flags & PMaxSize)) {
if (m_client->max_width != 0 && m_client->max_width <= m_client->min_width && if (client.max_width != 0 && client.max_width <= client.min_width &&
m_client->max_height != 0 && m_client->max_height <= m_client->min_height) { client.max_height != 0 && client.max_height <= client.min_height) {
decorations.maximize = false; decorations.maximize = false;
decorations.handle = false; decorations.handle = false;
functions.resize=false; functions.resize=false;
functions.maximize=false; functions.maximize=false;
} else { } else {
// TODO: is broken while handled by FbW, needs to be in WinClient // TODO: is broken while handled by FbW, needs to be in WinClient
if (! winClient().isTransient()) { if (! client.isTransient()) {
decorations.maximize = true; decorations.maximize = true;
decorations.handle = true; decorations.handle = true;
functions.maximize = true; functions.maximize = true;
} }
functions.resize = true; functions.resize = true;
} }
setupWindow();
} }
// save old values // save old values
@ -2159,13 +2155,16 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) {
} }
default: default:
if (atom == FbAtoms::instance()->getWMProtocolsAtom()) { FbAtoms *fbatoms = FbAtoms::instance();
m_client->updateWMProtocols(); if (atom == fbatoms->getWMProtocolsAtom()) {
//!!TODO check this area client.updateWMProtocols();
// reset window actions } else if (atom == fbatoms->getMWMHintsAtom()) {
setupWindow(); client.updateMWMHints();
updateMWMHintsFromClient(client);
} } else if (atom == fbatoms->getFluxboxHintsAtom()) {
client.updateBlackboxHints();
updateBlackboxHintsFromClient(client);
}
break; break;
} }
@ -2208,11 +2207,12 @@ void FluxboxWindow::configureRequestEvent(XConfigureRequestEvent &cr) {
// the request is for client window so we resize the frame to it first // the request is for client window so we resize the frame to it first
if (frame().width() != cw || frame().height() != ch) { 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; send_notify = true;
} } else if (frame().x() != cx || frame().y() != cy) {
if (frame().x() != cx || frame().y() != cy) {
move(cx, cy); move(cx, cy);
// since we already send a notify in move we don't need to do that again // since we already send a notify in move we don't need to do that again
send_notify = false; send_notify = false;
@ -2627,7 +2627,7 @@ void FluxboxWindow::applyDecorations(bool initial) {
// if the location changes, shift it // if the location changes, shift it
if (grav_x != 0 || grav_y != 0) 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(); frame().reconfigure();
} }

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // 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 #ifndef WINDOW_HH
#define WINDOW_HH #define WINDOW_HH
@ -236,7 +236,7 @@ public:
void unmapNotifyEvent(XUnmapEvent &unmapev); void unmapNotifyEvent(XUnmapEvent &unmapev);
void exposeEvent(XExposeEvent &ee); void exposeEvent(XExposeEvent &ee);
void configureRequestEvent(XConfigureRequestEvent &ce); void configureRequestEvent(XConfigureRequestEvent &ce);
void propertyNotifyEvent(Atom a); void propertyNotifyEvent(WinClient &client, Atom a);
void enterNotifyEvent(XCrossingEvent &ev); void enterNotifyEvent(XCrossingEvent &ev);
void leaveNotifyEvent(XCrossingEvent &ev); void leaveNotifyEvent(XCrossingEvent &ev);
//@} //@}
@ -374,11 +374,11 @@ private:
bool getState(); bool getState();
/// gets title string from client window and updates frame's title /// gets title string from client window and updates frame's title
void updateTitleFromClient(); void updateTitleFromClient(WinClient &client);
/// gets icon name from client window /// gets icon name from client window
void updateIconNameFromClient(); void updateIconNameFromClient(WinClient &client);
void getMWMHints(); void updateMWMHintsFromClient(WinClient &client);
void getBlackboxHints(); void updateBlackboxHintsFromClient(WinClient &client);
void saveBlackboxAttribs(); void saveBlackboxAttribs();
void setNetWMAttributes(); void setNetWMAttributes();
void associateClientWindow(); void associateClientWindow();