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)
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:

View file

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

View file

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

View file

@ -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;
window().move(x, y);
// update transparent only if we need to
if (theme().alpha() == 255)
return;
// restart update timer
m_update_timer.start();
/*
*/
moveResize(x, y, 0, 0, true, false);
}
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) {
moveResize(0, 0, width, height, false, true);
}
// 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_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) {

View file

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

View file

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

View file

@ -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();
}

View file

@ -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();