From 8033d09cceaedf36552c7c1be3e3667a324a4585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Tue, 27 Jul 2004 08:35:51 +0000 Subject: [PATCH] Dynamically detect changes of Motif hints instead of just reading them once initially. At least MPlayer changes them while mapped. svn path=/trunk/kdebase/kwin/; revision=333174 --- client.cpp | 24 +++++++++++++++++++++--- client.h | 4 +++- events.cpp | 2 ++ manage.cpp | 14 +------------- utils.cpp | 45 +++++++++++++-------------------------------- utils.h | 22 +++++++++++----------- 6 files changed, 51 insertions(+), 60 deletions(-) diff --git a/client.cpp b/client.cpp index 38443ccd96..976e10463c 100644 --- a/client.cpp +++ b/client.cpp @@ -112,6 +112,7 @@ Client::Client( Workspace *ws ) keep_above = FALSE; keep_below = FALSE; is_shape = FALSE; + motif_noborder = false; motif_may_move = TRUE; motif_may_resize = TRUE; motif_may_close = TRUE; @@ -324,9 +325,9 @@ void Client::checkBorderSizes() void Client::detectNoBorder() { - if( Shape::hasShape( window()) || Motif::noBorder( window())) + if( Shape::hasShape( window())) { - noborder = true; // TODO for all window types? + noborder = true; return; } switch( windowType()) @@ -382,7 +383,7 @@ void Client::resizeDecoration( const QSize& s ) bool Client::noBorder() const { - return noborder || isFullScreen() || user_noborder; + return noborder || isFullScreen() || user_noborder || motif_noborder; } bool Client::userCanSetNoBorder() const @@ -1308,6 +1309,23 @@ void Client::getWMHints() updateAllowedActions(); // group affects isMinimizable() } +void Client::getMotifHints() + { + bool mnoborder, mresize, mmove, mminimize, mmaximize, mclose; + Motif::readFlags( client, mnoborder, mresize, mmove, mminimize, mmaximize, mclose ); + motif_noborder = mnoborder; + if( !hasNETSupport()) // NETWM apps should set type and size constraints + { + motif_may_resize = mresize; // this should be set using minsize==maxsize, but oh well + motif_may_move = mmove; + } + // mminimize; - ignore, bogus - e.g. shading or sending to another desktop is "minimizing" too + // mmaximize; - ignore, bogus - maximizing is basically just resizing + motif_may_close = mclose; // motif apps like to crash when they set this hint and WM closes them anyway + if( isManaged()) + updateDecoration( true ); // check if noborder state has changed + } + void Client::readIcons( Window win, QPixmap* icon, QPixmap* miniicon ) { // get the icons, allow scaling diff --git a/client.h b/client.h index 80dc2b9cb3..8c4eb2f2c8 100644 --- a/client.h +++ b/client.h @@ -274,7 +274,7 @@ class Client : public QObject, public KDecorationDefines void cancelAutoRaise(); void destroyClient(); -private slots: + private slots: void autoRaise(); void shadeHover(); @@ -331,6 +331,7 @@ private slots: QSize sizeForClientSize( const QSize&, Sizemode mode = SizemodeAny ) const; void changeMaximize( bool horizontal, bool vertical, bool adjust ); void getWmNormalHints(); + void getMotifHints(); void getIcons(); void getWmClientLeader(); void fetchName(); @@ -437,6 +438,7 @@ private slots: uint Pping : 1; // does it support _NET_WM_PING? uint input :1; // does the window want input in its wm_hints uint skip_pager : 1; + uint motif_noborder : 1; uint motif_may_resize : 1; uint motif_may_move :1; uint motif_may_close : 1; diff --git a/events.cpp b/events.cpp index c4981fb4fb..c8e31a7b1e 100644 --- a/events.cpp +++ b/events.cpp @@ -854,6 +854,8 @@ void Client::propertyNotifyEvent( XPropertyEvent* e ) getWmClientLeader(); else if( e->atom == qt_window_role ) window_role = staticWindowRole( window()); + else if( e->atom == atoms->motif_wm_hints ) + getMotifHints(); break; } } diff --git a/manage.cpp b/manage.cpp index 8063147aa1..ef05d478a2 100644 --- a/manage.cpp +++ b/manage.cpp @@ -80,19 +80,6 @@ bool Client::manage( Window w, bool isMapped ) cmap = attr.colormap; - bool mresize, mmove, mminimize, mmaximize, mclose; - if( Motif::funcFlags( client, mresize, mmove, mminimize, mmaximize, mclose )) - { - if( !hasNETSupport()) // NETWM apps should set type and size constraints - { - motif_may_resize = mresize; // this should be set using minsize==maxsize, but oh well - motif_may_move = mmove; - } - // mminimize; - ignore, bogus - e.g. shading or sending to another desktop is "minimizing" too - // mmaximize; - ignore, bogus - maximizing is basically just resizing - motif_may_close = mclose; // motif apps like to crash when they set this hint and WM closes them anyway - } - XClassHint classHint; if ( XGetClassHint( qt_xdisplay(), client, &classHint ) ) { @@ -122,6 +109,7 @@ bool Client::manage( Window w, bool isMapped ) getIcons(); getWindowProtocols(); getWmNormalHints(); // get xSizeHint + getMotifHints(); // TODO try to obey all state information from info->state() diff --git a/utils.cpp b/utils.cpp index 9bb9ce157d..b6b58cbb74 100644 --- a/utils.cpp +++ b/utils.cpp @@ -63,35 +63,8 @@ void Shape::init() XShapeQueryExtension(qt_xdisplay(), &kwin_shape_event, &dummy); } -bool Motif::noBorder( WId w ) - { - Atom type; - int format; - unsigned long length, after; - unsigned char* data; - MwmHints* hints = 0; - if ( XGetWindowProperty( qt_xdisplay(), w, atoms->motif_wm_hints, 0, 5, - FALSE, atoms->motif_wm_hints, &type, &format, - &length, &after, &data ) == Success ) - { - if ( data ) - hints = (MwmHints*) data; - } - bool result = FALSE; - if ( hints ) - { - if ( hints->flags & MWM_HINTS_DECORATIONS ) - { - if ( hints->decorations == 0 ) - result = TRUE; - } - XFree( data ); - } - return result; - } - -bool Motif::funcFlags( WId w, bool& resize, bool& move, bool& minimize, - bool& maximize, bool& close ) +void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move, + bool& minimize, bool& maximize, bool& close ) { Atom type; int format; @@ -105,6 +78,12 @@ bool Motif::funcFlags( WId w, bool& resize, bool& move, bool& minimize, if ( data ) hints = (MwmHints*) data; } + noborder = false; + resize = true; + move = true; + minimize = true; + maximize = true; + close = true; if ( hints ) { // To quote from Metacity 'We support those MWM hints deemed non-stupid' @@ -123,12 +102,14 @@ bool Motif::funcFlags( WId w, bool& resize, bool& move, bool& minimize, maximize = set_value; if( hints->functions & MWM_FUNC_CLOSE ) close = set_value; - XFree( data ); - return true; + } + if ( hints->flags & MWM_HINTS_DECORATIONS ) + { + if ( hints->decorations == 0 ) + noborder = true; } XFree( data ); } - return false; } //************************************ diff --git a/utils.h b/utils.h index f02b7b7e28..b1988b4f40 100644 --- a/utils.h +++ b/utils.h @@ -122,9 +122,8 @@ class Shape class Motif { public: - static bool noBorder( WId w ); - static bool funcFlags( WId w, bool& resize, bool& move, bool& minimize, - bool& maximize, bool& close ); + static void readFlags( WId w, bool& noborder, bool& resize, bool& move, + bool& minimize, bool& maximize, bool& close ); struct MwmHints { ulong flags; @@ -133,15 +132,16 @@ class Motif long input_mode; ulong status; }; - enum { MWM_HINTS_FUNCTIONS = (1L << 0), - MWM_HINTS_DECORATIONS = (1L << 1), + enum { + MWM_HINTS_FUNCTIONS = (1L << 0), + MWM_HINTS_DECORATIONS = (1L << 1), - MWM_FUNC_ALL = (1L << 0), - MWM_FUNC_RESIZE = (1L << 1), - MWM_FUNC_MOVE = (1L << 2), - MWM_FUNC_MINIMIZE = (1L << 3), - MWM_FUNC_MAXIMIZE = (1L << 4), - MWM_FUNC_CLOSE = (1L << 5) + MWM_FUNC_ALL = (1L << 0), + MWM_FUNC_RESIZE = (1L << 1), + MWM_FUNC_MOVE = (1L << 2), + MWM_FUNC_MINIMIZE = (1L << 3), + MWM_FUNC_MAXIMIZE = (1L << 4), + MWM_FUNC_CLOSE = (1L << 5) }; };