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:
parent
1ca6f7a8b8
commit
8033d09cce
6 changed files with 51 additions and 60 deletions
24
client.cpp
24
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
|
||||
|
|
4
client.h
4
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
14
manage.cpp
14
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()
|
||||
|
||||
|
|
45
utils.cpp
45
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;
|
||||
}
|
||||
|
||||
//************************************
|
||||
|
|
22
utils.h
22
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)
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue