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
This commit is contained in:
Luboš Luňák 2004-07-27 08:35:51 +00:00
parent 1ca6f7a8b8
commit 8033d09cce
6 changed files with 51 additions and 60 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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,7 +132,8 @@ class Motif
long input_mode;
ulong status;
};
enum { MWM_HINTS_FUNCTIONS = (1L << 0),
enum {
MWM_HINTS_FUNCTIONS = (1L << 0),
MWM_HINTS_DECORATIONS = (1L << 1),
MWM_FUNC_ALL = (1L << 0),