Support for input shape from XShape1.1 (#122425).
svn path=/trunk/KDE/kdebase/workspace/; revision=571712
This commit is contained in:
parent
72d4e4205c
commit
293f093ea1
5 changed files with 621 additions and 389 deletions
585
client.cpp
585
client.cpp
|
@ -28,7 +28,6 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include "atoms.h"
|
||||
#include "notifications.h"
|
||||
#include "rules.h"
|
||||
#include "scene.h"
|
||||
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <QX11Info>
|
||||
|
@ -64,10 +63,12 @@ namespace KWinInternal
|
|||
is done in manage().
|
||||
*/
|
||||
Client::Client( Workspace *ws )
|
||||
: Toplevel( ws ),
|
||||
: QObject( NULL ),
|
||||
client( None ),
|
||||
wrapper( None ),
|
||||
frame( None ),
|
||||
decoration( NULL ),
|
||||
wspace( ws ),
|
||||
bridge( new Bridge( this )),
|
||||
move_faked_activity( false ),
|
||||
move_resize_grab_window( None ),
|
||||
|
@ -142,8 +143,11 @@ Client::Client( Workspace *ws )
|
|||
|
||||
cmap = None;
|
||||
|
||||
geom = QRect( 0, 0, 100, 100 ); // so that decorations don't start with size being (0,0)
|
||||
frame_geometry = QRect( 0, 0, 100, 100 ); // so that decorations don't start with size being (0,0)
|
||||
client_size = QSize( 100, 100 );
|
||||
custom_opacity = false;
|
||||
rule_opacity_active = 0;; //translucency rules
|
||||
rule_opacity_inactive = 0; //dito.
|
||||
|
||||
// SELI initialize xsizehints??
|
||||
}
|
||||
|
@ -155,8 +159,7 @@ Client::~Client()
|
|||
{
|
||||
assert(!moveResizeMode);
|
||||
assert( client == None );
|
||||
assert( wrapper == None );
|
||||
// assert( frameId() == None );
|
||||
assert( frame == None && wrapper == None );
|
||||
assert( decoration == NULL );
|
||||
assert( postpone_geometry_updates == 0 );
|
||||
assert( !check_active_modal );
|
||||
|
@ -177,9 +180,9 @@ void Client::releaseWindow( bool on_shutdown )
|
|||
{
|
||||
assert( !deleting );
|
||||
deleting = true;
|
||||
finishCompositing();
|
||||
workspace()->discardUsedWindowRules( this, true ); // remove ForceTemporarily rules
|
||||
StackingUpdatesBlocker blocker( workspace());
|
||||
if (!custom_opacity) setOpacity(false);
|
||||
if (moveResizeMode)
|
||||
leaveMoveResize();
|
||||
finishWindowRules();
|
||||
|
@ -189,7 +192,7 @@ void Client::releaseWindow( bool on_shutdown )
|
|||
hidden = true; // so that it's not considered visible anymore (can't use hideClient(), it would set flags)
|
||||
if( !on_shutdown )
|
||||
workspace()->clientHidden( this );
|
||||
XUnmapWindow( display(), frameId()); // destroying decoration would cause ugly visual effect
|
||||
XUnmapWindow( QX11Info::display(), frameId()); // destroying decoration would cause ugly visual effect
|
||||
destroyDecoration();
|
||||
cleanGrouping();
|
||||
if( !on_shutdown )
|
||||
|
@ -201,28 +204,28 @@ void Client::releaseWindow( bool on_shutdown )
|
|||
desk = 0;
|
||||
info->setState( 0, info->state()); // reset all state flags
|
||||
}
|
||||
XDeleteProperty( display(), client, atoms->kde_net_wm_user_creation_time);
|
||||
XDeleteProperty( display(), client, atoms->net_frame_extents );
|
||||
XDeleteProperty( display(), client, atoms->kde_net_wm_frame_strut );
|
||||
XReparentWindow( display(), client, workspace()->rootWin(), x(), y());
|
||||
XRemoveFromSaveSet( display(), client );
|
||||
XSelectInput( display(), client, NoEventMask );
|
||||
XDeleteProperty( QX11Info::display(), client, atoms->kde_net_wm_user_creation_time);
|
||||
XDeleteProperty( QX11Info::display(), client, atoms->net_frame_extents );
|
||||
XDeleteProperty( QX11Info::display(), client, atoms->kde_net_wm_frame_strut );
|
||||
XReparentWindow( QX11Info::display(), client, workspace()->rootWin(), x(), y());
|
||||
XRemoveFromSaveSet( QX11Info::display(), client );
|
||||
XSelectInput( QX11Info::display(), client, NoEventMask );
|
||||
if( on_shutdown )
|
||||
{ // map the window, so it can be found after another WM is started
|
||||
XMapWindow( display(), client );
|
||||
XMapWindow( QX11Info::display(), client );
|
||||
// TODO preserve minimized, shaded etc. state?
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure it's not mapped if the app unmapped it (#65279). The app
|
||||
// may do map+unmap before we initially map the window by calling rawShow() from manage().
|
||||
XUnmapWindow( display(), client );
|
||||
XUnmapWindow( QX11Info::display(), client );
|
||||
}
|
||||
client = None;
|
||||
XDestroyWindow( display(), wrapper );
|
||||
XDestroyWindow( QX11Info::display(), wrapper );
|
||||
wrapper = None;
|
||||
XDestroyWindow( display(), frameId());
|
||||
// frame = None;
|
||||
XDestroyWindow( QX11Info::display(), frame );
|
||||
frame = None;
|
||||
--postpone_geometry_updates; // don't use GeometryUpdatesBlocker, it would now set the geometry
|
||||
deleteClient( this, Allowed );
|
||||
}
|
||||
|
@ -233,7 +236,6 @@ void Client::destroyClient()
|
|||
{
|
||||
assert( !deleting );
|
||||
deleting = true;
|
||||
finishCompositing();
|
||||
workspace()->discardUsedWindowRules( this, true ); // remove ForceTemporarily rules
|
||||
StackingUpdatesBlocker blocker( workspace());
|
||||
if (moveResizeMode)
|
||||
|
@ -247,10 +249,10 @@ void Client::destroyClient()
|
|||
cleanGrouping();
|
||||
workspace()->removeClient( this, Allowed );
|
||||
client = None; // invalidate
|
||||
XDestroyWindow( display(), wrapper );
|
||||
XDestroyWindow( QX11Info::display(), wrapper );
|
||||
wrapper = None;
|
||||
XDestroyWindow( display(), frameId());
|
||||
// frame = None;
|
||||
XDestroyWindow( QX11Info::display(), frame );
|
||||
frame = None;
|
||||
--postpone_geometry_updates; // don't use GeometryUpdatesBlocker, it would now set the geometry
|
||||
deleteClient( this, Allowed );
|
||||
}
|
||||
|
@ -270,9 +272,12 @@ void Client::updateDecoration( bool check_workspace_pos, bool force )
|
|||
// TODO check decoration's minimum size?
|
||||
decoration->init();
|
||||
decoration->widget()->installEventFilter( this );
|
||||
XReparentWindow( display(), decoration->widget()->winId(), frameId(), 0, 0 );
|
||||
XReparentWindow( QX11Info::display(), decoration->widget()->winId(), frameId(), 0, 0 );
|
||||
decoration->widget()->lower();
|
||||
decoration->borders( border_left, border_right, border_top, border_bottom );
|
||||
options->onlyDecoTranslucent ?
|
||||
setDecoHashProperty(border_top, border_right, border_bottom, border_left):
|
||||
unsetDecoHashProperty();
|
||||
int save_workarea_diff_x = workarea_diff_x;
|
||||
int save_workarea_diff_y = workarea_diff_y;
|
||||
move( calculateGravitation( false ));
|
||||
|
@ -280,8 +285,6 @@ void Client::updateDecoration( bool check_workspace_pos, bool force )
|
|||
workarea_diff_x = save_workarea_diff_x;
|
||||
workarea_diff_y = save_workarea_diff_y;
|
||||
do_show = true;
|
||||
if( scene != NULL )
|
||||
scene->windowGeometryShapeChanged( this );
|
||||
}
|
||||
else
|
||||
destroyDecoration();
|
||||
|
@ -308,8 +311,6 @@ void Client::destroyDecoration()
|
|||
move( grav );
|
||||
workarea_diff_x = save_workarea_diff_x;
|
||||
workarea_diff_y = save_workarea_diff_y;
|
||||
if( scene != NULL )
|
||||
scene->windowGeometryShapeChanged( this );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,6 +333,9 @@ void Client::checkBorderSizes()
|
|||
border_right != new_right ||
|
||||
border_top != new_top ||
|
||||
border_bottom != new_bottom)
|
||||
options->onlyDecoTranslucent ?
|
||||
setDecoHashProperty(new_top, new_right, new_bottom, new_left):
|
||||
unsetDecoHashProperty();
|
||||
move( calculateGravitation( false ));
|
||||
plainResize( sizeForClientSize( clientSize()), ForceGeometrySet );
|
||||
checkWorkspacePosition();
|
||||
|
@ -339,7 +343,7 @@ void Client::checkBorderSizes()
|
|||
|
||||
void Client::detectNoBorder()
|
||||
{
|
||||
if( hasShape( window()))
|
||||
if( Shape::hasShape( window()))
|
||||
{
|
||||
noborder = true;
|
||||
return;
|
||||
|
@ -370,6 +374,30 @@ void Client::detectNoBorder()
|
|||
noborder = true;
|
||||
}
|
||||
|
||||
void Client::detectShapable()
|
||||
{
|
||||
if( Shape::hasShape( window()))
|
||||
return;
|
||||
switch( windowType())
|
||||
{
|
||||
case NET::Desktop :
|
||||
case NET::Dock :
|
||||
case NET::TopMenu :
|
||||
case NET::Splash :
|
||||
break;
|
||||
case NET::Unknown :
|
||||
case NET::Normal :
|
||||
case NET::Toolbar :
|
||||
case NET::Menu :
|
||||
case NET::Dialog :
|
||||
case NET::Utility :
|
||||
setShapable(false);
|
||||
break;
|
||||
default:
|
||||
assert( false );
|
||||
}
|
||||
}
|
||||
|
||||
void Client::updateFrameExtents()
|
||||
{
|
||||
NETStrut strut;
|
||||
|
@ -427,31 +455,46 @@ void Client::setUserNoBorder( bool set )
|
|||
|
||||
void Client::updateShape()
|
||||
{
|
||||
if ( shape() )
|
||||
XShapeCombineShape(display(), frameId(), ShapeBounding,
|
||||
clientPos().x(), clientPos().y(),
|
||||
window(), ShapeBounding, ShapeSet);
|
||||
else
|
||||
XShapeCombineMask( display(), frameId(), ShapeBounding, 0, 0,
|
||||
None, ShapeSet);
|
||||
if( scene != NULL )
|
||||
scene->windowGeometryShapeChanged( this );
|
||||
// workaround for #19644 - shaped windows shouldn't have decoration
|
||||
if( shape() && !noBorder())
|
||||
{
|
||||
noborder = true;
|
||||
updateDecoration( true );
|
||||
}
|
||||
if( shape())
|
||||
{
|
||||
XShapeCombineShape(QX11Info::display(), frameId(), ShapeBounding,
|
||||
clientPos().x(), clientPos().y(),
|
||||
window(), ShapeBounding, ShapeSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
XShapeCombineMask( QX11Info::display(), frameId(), ShapeBounding, 0, 0,
|
||||
None, ShapeSet);
|
||||
}
|
||||
if( Shape::major() > 1 || Shape::minor() >= 1 ) // has input shape support
|
||||
{ // there appears to be no way to find out if a window has input
|
||||
// shape set or not, so always set propagate the input shape
|
||||
// (it's the same like the bounding shape by default)
|
||||
XShapeCombineMask( QX11Info::display(), frameId(), ShapeInput, 0, 0,
|
||||
None, ShapeSet );
|
||||
XShapeCombineShape( QX11Info::display(), frameId(), ShapeInput,
|
||||
clientPos().x(), clientPos().y(),
|
||||
window(), ShapeBounding, ShapeSubtract );
|
||||
XShapeCombineShape( QX11Info::display(), frameId(), ShapeInput,
|
||||
clientPos().x(), clientPos().y(),
|
||||
window(), ShapeInput, ShapeUnion );
|
||||
}
|
||||
}
|
||||
|
||||
void Client::setMask( const QRegion& reg, int mode )
|
||||
{
|
||||
_mask = reg;
|
||||
if( reg.isEmpty())
|
||||
XShapeCombineMask( display(), frameId(), ShapeBounding, 0, 0,
|
||||
XShapeCombineMask( QX11Info::display(), frameId(), ShapeBounding, 0, 0,
|
||||
None, ShapeSet );
|
||||
else if( mode == X::Unsorted )
|
||||
XShapeCombineRegion( display(), frameId(), ShapeBounding, 0, 0,
|
||||
XShapeCombineRegion( QX11Info::display(), frameId(), ShapeBounding, 0, 0,
|
||||
reg.handle(), ShapeSet );
|
||||
else
|
||||
{
|
||||
|
@ -466,12 +509,10 @@ void Client::setMask( const QRegion& reg, int mode )
|
|||
xrects[ i ].width = rects[ i ].width();
|
||||
xrects[ i ].height = rects[ i ].height();
|
||||
}
|
||||
XShapeCombineRectangles( display(), frameId(), ShapeBounding, 0, 0,
|
||||
XShapeCombineRectangles( QX11Info::display(), frameId(), ShapeBounding, 0, 0,
|
||||
xrects, rects.count(), ShapeSet, mode );
|
||||
delete[] xrects;
|
||||
}
|
||||
if( scene != NULL )
|
||||
scene->windowGeometryShapeChanged( this );
|
||||
}
|
||||
|
||||
QRegion Client::mask() const
|
||||
|
@ -481,6 +522,12 @@ QRegion Client::mask() const
|
|||
return _mask;
|
||||
}
|
||||
|
||||
void Client::setShapable(bool b)
|
||||
{
|
||||
long tmp = b?1:0;
|
||||
XChangeProperty(QX11Info::display(), frameId(), atoms->net_wm_window_shapable, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &tmp, 1L);
|
||||
}
|
||||
|
||||
void Client::hideClient( bool hide )
|
||||
{
|
||||
if( hidden == hide )
|
||||
|
@ -632,7 +679,7 @@ void Client::animateMinimizeOrUnminimize( bool minimize )
|
|||
if (area2 != area)
|
||||
{
|
||||
pm = animationPixmap( area.width() );
|
||||
pm2 = QPixmap::grabWindow( rootWindow(), area.x(), area.y(), area.width(), area.height() );
|
||||
pm2 = QPixmap::grabWindow( QX11Info::appRootWindow(), area.x(), area.y(), area.width(), area.height() );
|
||||
p.drawPixmap( area.x(), area.y(), pm );
|
||||
if ( need_to_clear )
|
||||
{
|
||||
|
@ -641,8 +688,8 @@ void Client::animateMinimizeOrUnminimize( bool minimize )
|
|||
}
|
||||
area2 = area;
|
||||
}
|
||||
XFlush(display());
|
||||
XSync( display(), false );
|
||||
XFlush(QX11Info::display());
|
||||
XSync( QX11Info::display(), false );
|
||||
diff = t.elapsed();
|
||||
if (diff > step)
|
||||
diff = step;
|
||||
|
@ -730,16 +777,16 @@ void Client::setShade( ShadeMode mode )
|
|||
{ // shade_mode == ShadeNormal
|
||||
// we're about to shade, texx xcompmgr to prepare
|
||||
long _shade = 1;
|
||||
XChangeProperty(display(), frameId(), atoms->net_wm_window_shade, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &_shade, 1L);
|
||||
XChangeProperty(QX11Info::display(), frameId(), atoms->net_wm_window_shade, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &_shade, 1L);
|
||||
// shade
|
||||
int h = height();
|
||||
shade_geometry_change = true;
|
||||
QSize s( sizeForClientSize( QSize( clientSize())));
|
||||
s.setHeight( border_top + border_bottom );
|
||||
XSelectInput( display(), wrapper, ClientWinMask ); // avoid getting UnmapNotify
|
||||
XUnmapWindow( display(), wrapper );
|
||||
XUnmapWindow( display(), client );
|
||||
XSelectInput( display(), wrapper, ClientWinMask | SubstructureNotifyMask );
|
||||
XSelectInput( QX11Info::display(), wrapper, ClientWinMask ); // avoid getting UnmapNotify
|
||||
XUnmapWindow( QX11Info::display(), wrapper );
|
||||
XUnmapWindow( QX11Info::display(), client );
|
||||
XSelectInput( QX11Info::display(), wrapper, ClientWinMask | SubstructureNotifyMask );
|
||||
//as we hid the unmap event, xcompmgr didn't recognize the client wid has vanished, so we'll extra inform it
|
||||
//done xcompmgr workaround
|
||||
// FRAME repaint( false );
|
||||
|
@ -749,7 +796,7 @@ void Client::setShade( ShadeMode mode )
|
|||
do
|
||||
{
|
||||
h -= step;
|
||||
XResizeWindow( display(), frameId(), s.width(), h );
|
||||
XResizeWindow( QX11Info::display(), frameId(), s.width(), h );
|
||||
resizeDecoration( QSize( s.width(), h ));
|
||||
QApplication::syncX();
|
||||
} while ( h > s.height() + step );
|
||||
|
@ -766,7 +813,7 @@ void Client::setShade( ShadeMode mode )
|
|||
}
|
||||
// tell xcompmgr shade's done
|
||||
_shade = 2;
|
||||
XChangeProperty(display(), frameId(), atoms->net_wm_window_shade, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &_shade, 1L);
|
||||
XChangeProperty(QX11Info::display(), frameId(), atoms->net_wm_window_shade, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &_shade, 1L);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -779,7 +826,7 @@ void Client::setShade( ShadeMode mode )
|
|||
do
|
||||
{
|
||||
h += step;
|
||||
XResizeWindow( display(), frameId(), s.width(), h );
|
||||
XResizeWindow( QX11Info::display(), frameId(), s.width(), h );
|
||||
resizeDecoration( QSize( s.width(), h ));
|
||||
// assume a border
|
||||
// we do not have time to wait for X to send us paint events
|
||||
|
@ -792,9 +839,9 @@ void Client::setShade( ShadeMode mode )
|
|||
plainResize( s );
|
||||
if( shade_mode == ShadeHover || shade_mode == ShadeActivated )
|
||||
setActive( true );
|
||||
XMapWindow( display(), wrapperId());
|
||||
XMapWindow( display(), window());
|
||||
XDeleteProperty (display(), client, atoms->net_wm_window_shade);
|
||||
XMapWindow( QX11Info::display(), wrapperId());
|
||||
XMapWindow( QX11Info::display(), window());
|
||||
XDeleteProperty (QX11Info::display(), client, atoms->net_wm_window_shade);
|
||||
if ( isActive() )
|
||||
workspace()->requestFocus( this );
|
||||
}
|
||||
|
@ -893,7 +940,7 @@ void Client::setMappingState(int s)
|
|||
mapping_state = s;
|
||||
if( mapping_state == WithdrawnState )
|
||||
{
|
||||
XDeleteProperty( display(), window(), atoms->wm_state );
|
||||
XDeleteProperty( QX11Info::display(), window(), atoms->wm_state );
|
||||
return;
|
||||
}
|
||||
assert( s == NormalState || s == IconicState );
|
||||
|
@ -901,7 +948,7 @@ void Client::setMappingState(int s)
|
|||
unsigned long data[2];
|
||||
data[0] = (unsigned long) s;
|
||||
data[1] = (unsigned long) None;
|
||||
XChangeProperty(display(), window(), atoms->wm_state, atoms->wm_state, 32,
|
||||
XChangeProperty(QX11Info::display(), window(), atoms->wm_state, atoms->wm_state, 32,
|
||||
PropModeReplace, (unsigned char *)data, 2);
|
||||
|
||||
if( was_unmanaged ) // manage() did postpone_geometry_updates = 1, now it's ok to finally set the geometry
|
||||
|
@ -916,11 +963,11 @@ void Client::rawShow()
|
|||
{
|
||||
if( decoration != NULL )
|
||||
decoration->widget()->show(); // not really necessary, but let it know the state
|
||||
XMapWindow( display(), frameId());
|
||||
XMapWindow( QX11Info::display(), frame );
|
||||
if( !isShade())
|
||||
{
|
||||
XMapWindow( display(), wrapper );
|
||||
XMapWindow( display(), client );
|
||||
XMapWindow( QX11Info::display(), wrapper );
|
||||
XMapWindow( QX11Info::display(), client );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -937,11 +984,11 @@ void Client::rawHide()
|
|||
// which won't be missed, so this shouldn't be a problem. The chance the real UnmapNotify
|
||||
// will be missed is also very minimal, so I don't think it's needed to grab the server
|
||||
// here.
|
||||
XSelectInput( display(), wrapper, ClientWinMask ); // avoid getting UnmapNotify
|
||||
XUnmapWindow( display(), frameId());
|
||||
XUnmapWindow( display(), wrapper );
|
||||
XUnmapWindow( display(), client );
|
||||
XSelectInput( display(), wrapper, ClientWinMask | SubstructureNotifyMask );
|
||||
XSelectInput( QX11Info::display(), wrapper, ClientWinMask ); // avoid getting UnmapNotify
|
||||
XUnmapWindow( QX11Info::display(), frame );
|
||||
XUnmapWindow( QX11Info::display(), wrapper );
|
||||
XUnmapWindow( QX11Info::display(), client );
|
||||
XSelectInput( QX11Info::display(), wrapper, ClientWinMask | SubstructureNotifyMask );
|
||||
if( decoration != NULL )
|
||||
decoration->widget()->hide(); // not really necessary, but let it know the state
|
||||
workspace()->clientHidden( this );
|
||||
|
@ -958,14 +1005,14 @@ void Client::sendClientMessage(Window w, Atom a, Atom protocol, long data1, long
|
|||
ev.xclient.message_type = a;
|
||||
ev.xclient.format = 32;
|
||||
ev.xclient.data.l[0] = protocol;
|
||||
ev.xclient.data.l[1] = xTime();
|
||||
ev.xclient.data.l[1] = QX11Info::appTime();
|
||||
ev.xclient.data.l[2] = data1;
|
||||
ev.xclient.data.l[3] = data2;
|
||||
ev.xclient.data.l[4] = data3;
|
||||
mask = 0L;
|
||||
if (w == rootWindow())
|
||||
if (w == QX11Info::appRootWindow())
|
||||
mask = SubstructureRedirectMask; /* magic! */
|
||||
XSendEvent(display(), w, False, mask, &ev);
|
||||
XSendEvent(QX11Info::display(), w, False, mask, &ev);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1017,7 +1064,7 @@ void Client::killWindow()
|
|||
Notify::raise( Notify::Delete );
|
||||
killProcess( false );
|
||||
// always kill this client at the server
|
||||
XKillClient(display(), window() );
|
||||
XKillClient(QX11Info::display(), window() );
|
||||
destroyClient();
|
||||
}
|
||||
|
||||
|
@ -1036,7 +1083,7 @@ void Client::pingWindow()
|
|||
connect( ping_timer, SIGNAL( timeout()), SLOT( pingTimeout()));
|
||||
ping_timer->setSingleShot( true );
|
||||
ping_timer->start( options->killPingTimeout );
|
||||
ping_timestamp = xTime();
|
||||
ping_timestamp = QX11Info::appTime();
|
||||
workspace()->sendPingToWindow( window(), ping_timestamp );
|
||||
}
|
||||
|
||||
|
@ -1203,15 +1250,15 @@ void Client::takeActivity( int flags, bool handled, allowed_t )
|
|||
#ifndef NDEBUG
|
||||
static Time previous_activity_timestamp;
|
||||
static Client* previous_client;
|
||||
if( previous_activity_timestamp == xTime() && previous_client != this )
|
||||
if( previous_activity_timestamp == QX11Info::appTime() && previous_client != this )
|
||||
{
|
||||
kDebug( 1212 ) << "Repeated use of the same X timestamp for activity" << endl;
|
||||
kDebug( 1212 ) << kBacktrace() << endl;
|
||||
}
|
||||
previous_activity_timestamp = xTime();
|
||||
previous_activity_timestamp = QX11Info::appTime();
|
||||
previous_client = this;
|
||||
#endif
|
||||
workspace()->sendTakeActivity( this, xTime(), flags );
|
||||
workspace()->sendTakeActivity( this, QX11Info::appTime(), flags );
|
||||
}
|
||||
|
||||
// performs the actual focusing of the window using XSetInputFocus and WM_TAKE_FOCUS
|
||||
|
@ -1220,17 +1267,17 @@ void Client::takeFocus( allowed_t )
|
|||
#ifndef NDEBUG
|
||||
static Time previous_focus_timestamp;
|
||||
static Client* previous_client;
|
||||
if( previous_focus_timestamp == xTime() && previous_client != this )
|
||||
if( previous_focus_timestamp == QX11Info::appTime() && previous_client != this )
|
||||
{
|
||||
kDebug( 1212 ) << "Repeated use of the same X timestamp for focus" << endl;
|
||||
kDebug( 1212 ) << kBacktrace() << endl;
|
||||
}
|
||||
previous_focus_timestamp = xTime();
|
||||
previous_focus_timestamp = QX11Info::appTime();
|
||||
previous_client = this;
|
||||
#endif
|
||||
if ( rules()->checkAcceptFocus( input ))
|
||||
{
|
||||
XSetInputFocus( display(), window(), RevertToPointerRoot, xTime() );
|
||||
XSetInputFocus( QX11Info::display(), window(), RevertToPointerRoot, QX11Info::appTime() );
|
||||
}
|
||||
if ( Ptakefocus )
|
||||
sendClientMessage(window(), atoms->wm_protocols, atoms->wm_take_focus);
|
||||
|
@ -1283,7 +1330,7 @@ QString Client::readName() const
|
|||
return KWin::readNameProperty( window(), XA_WM_NAME );
|
||||
}
|
||||
|
||||
KWIN_COMPARE_PREDICATE( FetchNameInternalPredicate, Client, const Client*, (!cl->isSpecialWindow() || cl->isToolbar()) && cl != value && cl->caption() == value->caption());
|
||||
KWIN_COMPARE_PREDICATE( FetchNameInternalPredicate, const Client*, (!cl->isSpecialWindow() || cl->isToolbar()) && cl != value && cl->caption() == value->caption());
|
||||
|
||||
void Client::setCaption( const QString& _s, bool force )
|
||||
{
|
||||
|
@ -1363,7 +1410,7 @@ QString Client::caption( bool full ) const
|
|||
|
||||
void Client::getWMHints()
|
||||
{
|
||||
XWMHints *hints = XGetWMHints(display(), window() );
|
||||
XWMHints *hints = XGetWMHints(QX11Info::display(), window() );
|
||||
input = true;
|
||||
window_group = None;
|
||||
urgency = false;
|
||||
|
@ -1452,7 +1499,7 @@ void Client::getWindowProtocols()
|
|||
Pcontexthelp = 0;
|
||||
Pping = 0;
|
||||
|
||||
if (XGetWMProtocols(display(), window(), &p, &n))
|
||||
if (XGetWMProtocols(QX11Info::display(), window(), &p, &n))
|
||||
{
|
||||
for (i = 0; i < n; i++)
|
||||
if (p[i] == atoms->wm_delete_window)
|
||||
|
@ -1511,7 +1558,7 @@ Window Client::staticWmClientLeader(WId w)
|
|||
unsigned char *data = 0;
|
||||
Window result = w;
|
||||
XErrorHandler oldHandler = XSetErrorHandler(nullErrorHandler);
|
||||
status = XGetWindowProperty( display(), w, atoms->wm_client_leader, 0, 10000,
|
||||
status = XGetWindowProperty( QX11Info::display(), w, atoms->wm_client_leader, 0, 10000,
|
||||
false, XA_WINDOW, &type, &format,
|
||||
&nitems, &extra, &data );
|
||||
XSetErrorHandler(oldHandler);
|
||||
|
@ -1600,6 +1647,58 @@ bool Client::wantsInput() const
|
|||
return rules()->checkAcceptFocus( input || Ptakefocus );
|
||||
}
|
||||
|
||||
bool Client::isDesktop() const
|
||||
{
|
||||
return windowType() == NET::Desktop;
|
||||
}
|
||||
|
||||
bool Client::isDock() const
|
||||
{
|
||||
return windowType() == NET::Dock;
|
||||
}
|
||||
|
||||
bool Client::isTopMenu() const
|
||||
{
|
||||
return windowType() == NET::TopMenu;
|
||||
}
|
||||
|
||||
|
||||
bool Client::isMenu() const
|
||||
{
|
||||
return windowType() == NET::Menu && !isTopMenu(); // because of backwards comp.
|
||||
}
|
||||
|
||||
bool Client::isToolbar() const
|
||||
{
|
||||
return windowType() == NET::Toolbar;
|
||||
}
|
||||
|
||||
bool Client::isSplash() const
|
||||
{
|
||||
return windowType() == NET::Splash;
|
||||
}
|
||||
|
||||
bool Client::isUtility() const
|
||||
{
|
||||
return windowType() == NET::Utility;
|
||||
}
|
||||
|
||||
bool Client::isDialog() const
|
||||
{
|
||||
return windowType() == NET::Dialog;
|
||||
}
|
||||
|
||||
bool Client::isNormalWindow() const
|
||||
{
|
||||
return windowType() == NET::Normal;
|
||||
}
|
||||
|
||||
bool Client::isSpecialWindow() const
|
||||
{
|
||||
return isDesktop() || isDock() || isSplash() || isTopMenu()
|
||||
|| isToolbar(); // TODO
|
||||
}
|
||||
|
||||
NET::WindowType Client::windowType( bool direct, int supported_types ) const
|
||||
{
|
||||
NET::WindowType wt = info->windowType( supported_types );
|
||||
|
@ -1631,12 +1730,6 @@ NET::WindowType Client::windowType( bool direct, int supported_types ) const
|
|||
return wt;
|
||||
}
|
||||
|
||||
bool Client::isSpecialWindow() const
|
||||
{
|
||||
return isDesktop() || isDock() || isSplash() || isTopMenu()
|
||||
|| isToolbar(); // TODO
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets an appropriate cursor shape for the logical mouse position \a m
|
||||
|
||||
|
@ -1682,7 +1775,7 @@ void Client::setCursor( const QCursor& c )
|
|||
cursor = c;
|
||||
if( decoration != NULL )
|
||||
decoration->widget()->setCursor( cursor );
|
||||
XDefineCursor( display(), frameId(), cursor.handle());
|
||||
XDefineCursor( QX11Info::display(), frameId(), cursor.handle());
|
||||
}
|
||||
|
||||
Client::Position Client::mousePosition( const QPoint& p ) const
|
||||
|
@ -1733,38 +1826,312 @@ void Client::cancelAutoRaise()
|
|||
autoRaiseTimer = 0;
|
||||
}
|
||||
|
||||
// does the window w need a shape combine mask around it?
|
||||
bool Client::hasShape( Window w )
|
||||
void Client::setOpacity(bool translucent, uint opacity)
|
||||
{
|
||||
int xws, yws, xbs, ybs;
|
||||
unsigned int wws, hws, wbs, hbs;
|
||||
int boundingShaped = 0, clipShaped = 0;
|
||||
if( !Extensions::shapeAvailable())
|
||||
return false;
|
||||
XShapeQueryExtents(display(), w,
|
||||
&boundingShaped, &xws, &yws, &wws, &hws,
|
||||
&clipShaped, &xbs, &ybs, &wbs, &hbs);
|
||||
return boundingShaped != 0;
|
||||
if (isDesktop())
|
||||
return; // xcompmgr does not like non solid desktops and the user could set it accidently by mouse scrolling
|
||||
// qWarning("setting opacity for %d",QX11Info::display());
|
||||
//rule out activated translulcency with 100% opacity
|
||||
if (!translucent || opacity == 0xFFFFFFFF)
|
||||
{
|
||||
opacity_ = 0xFFFFFFFF;
|
||||
XDeleteProperty (QX11Info::display(), frameId(), atoms->net_wm_window_opacity);
|
||||
XDeleteProperty (QX11Info::display(), window(), atoms->net_wm_window_opacity); // ??? frameId() is necessary for visible changes, window() is the winId() that would be set by apps - we set both to be sure the app knows what's currently displayd
|
||||
}
|
||||
else{
|
||||
if(opacity == opacity_)
|
||||
return;
|
||||
opacity_ = opacity;
|
||||
long data = opacity; // 32bit XChangeProperty needs long
|
||||
XChangeProperty(QX11Info::display(), frameId(), atoms->net_wm_window_opacity, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &data, 1L);
|
||||
XChangeProperty(QX11Info::display(), window(), atoms->net_wm_window_opacity, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &data, 1L);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::setShadowSize(uint shadowSize)
|
||||
{
|
||||
// ignoring all individual settings - if we control a window, we control it's shadow
|
||||
// TODO somehow handle individual settings for docks (besides custom sizes)
|
||||
long data = shadowSize;
|
||||
XChangeProperty(QX11Info::display(), frameId(), atoms->net_wm_window_shadow, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &data, 1L);
|
||||
}
|
||||
|
||||
void Client::updateOpacity()
|
||||
// extra syncscreen flag allows to avoid double syncs when active state changes (as it will usually change for two windows)
|
||||
{
|
||||
if (!(isNormalWindow() || isDialog() || isUtility() )|| custom_opacity)
|
||||
return;
|
||||
if (isActive())
|
||||
{
|
||||
if( ruleOpacityActive() )
|
||||
setOpacity(rule_opacity_active < 0xFFFFFFFF, rule_opacity_active);
|
||||
else
|
||||
setOpacity(options->translucentActiveWindows, options->activeWindowOpacity);
|
||||
if (isBMP())
|
||||
// beep-media-player, only undecorated windows (gtk2 xmms, xmms doesn't work with compmgr at all - s.e.p. :P )
|
||||
{
|
||||
ClientList tmpGroupMembers = group()->members();
|
||||
ClientList activeGroupMembers;
|
||||
activeGroupMembers.append(this);
|
||||
tmpGroupMembers.removeAll(this);
|
||||
ClientList::Iterator it = tmpGroupMembers.begin();
|
||||
while (it != tmpGroupMembers.end())
|
||||
// search for next attached and not activated client and repeat if found
|
||||
{
|
||||
if ((*it) != this && (*it)->isBMP())
|
||||
// potential "to activate" client found
|
||||
{
|
||||
// qWarning("client found");
|
||||
if ((*it)->touches(this)) // first test, if the new client touches the just activated one
|
||||
{
|
||||
// qWarning("found client touches me");
|
||||
if( ruleOpacityActive() )
|
||||
(*it)->setOpacity(rule_opacity_active < 0xFFFFFFFF, rule_opacity_active);
|
||||
else
|
||||
(*it)->setOpacity(options->translucentActiveWindows, options->activeWindowOpacity);
|
||||
// qWarning("activated, search restarted (1)");
|
||||
(*it)->setShadowSize(options->activeWindowShadowSize);
|
||||
activeGroupMembers.append(*it);
|
||||
tmpGroupMembers.erase(it);
|
||||
it = tmpGroupMembers.begin(); // restart, search next client
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{ // pot. client does not touch c, so we have to search if it touches some other activated client
|
||||
bool found = false;
|
||||
for( ClientList::ConstIterator it2 = activeGroupMembers.begin(); it2 != activeGroupMembers.end(); it2++ )
|
||||
{
|
||||
if ((*it2) != this && (*it2) != (*it) && (*it)->touches(*it2))
|
||||
{
|
||||
// qWarning("found client touches other active client");
|
||||
if( ruleOpacityActive() )
|
||||
(*it)->setOpacity(rule_opacity_active < 0xFFFFFFFF, rule_opacity_active);
|
||||
else
|
||||
(*it)->setOpacity(options->translucentActiveWindows, options->activeWindowOpacity);
|
||||
(*it)->setShadowSize(options->activeWindowShadowSize);
|
||||
activeGroupMembers.append(*it);
|
||||
tmpGroupMembers.erase(it);
|
||||
it = tmpGroupMembers.begin(); // reset potential client search
|
||||
found = true;
|
||||
// qWarning("activated, search restarted (2)");
|
||||
break; // skip this loop
|
||||
}
|
||||
}
|
||||
if (found) continue;
|
||||
}
|
||||
}
|
||||
it++;
|
||||
}
|
||||
}
|
||||
else if (isNormalWindow())
|
||||
// activate dependent minor windows as well
|
||||
{
|
||||
for( ClientList::ConstIterator it = group()->members().begin(); it != group()->members().end(); it++ )
|
||||
if ((*it)->isDialog() || (*it)->isUtility())
|
||||
if( (*it)->ruleOpacityActive() )
|
||||
(*it)->setOpacity((*it)->ruleOpacityActive() < 0xFFFFFFFF, (*it)->ruleOpacityActive());
|
||||
else
|
||||
(*it)->setOpacity(options->translucentActiveWindows, options->activeWindowOpacity);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ruleOpacityInactive() )
|
||||
setOpacity(rule_opacity_inactive < 0xFFFFFFFF, rule_opacity_inactive);
|
||||
else
|
||||
setOpacity(options->translucentInactiveWindows && !(keepAbove() && options->keepAboveAsActive),
|
||||
options->inactiveWindowOpacity);
|
||||
// deactivate dependent minor windows as well
|
||||
if (isBMP())
|
||||
// beep-media-player, only undecorated windows (gtk2 xmms, xmms doesn't work with compmgr at all - s.e.p. :P )
|
||||
{
|
||||
ClientList tmpGroupMembers = group()->members();
|
||||
ClientList inactiveGroupMembers;
|
||||
inactiveGroupMembers.append(this);
|
||||
tmpGroupMembers.removeAll(this);
|
||||
ClientList::Iterator it = tmpGroupMembers.begin();
|
||||
while ( it != tmpGroupMembers.end() )
|
||||
// search for next attached and not activated client and repeat if found
|
||||
{
|
||||
if ((*it) != this && (*it)->isBMP())
|
||||
// potential "to activate" client found
|
||||
{
|
||||
// qWarning("client found");
|
||||
if ((*it)->touches(this)) // first test, if the new client touches the just activated one
|
||||
{
|
||||
// qWarning("found client touches me");
|
||||
if( (*it)->ruleOpacityInactive() )
|
||||
(*it)->setOpacity((*it)->ruleOpacityInactive() < 0xFFFFFFFF, (*it)->ruleOpacityInactive());
|
||||
else
|
||||
(*it)->setOpacity(options->translucentInactiveWindows && !((*it)->keepAbove() && options->keepAboveAsActive), options->inactiveWindowOpacity);
|
||||
(*it)->setShadowSize(options->inactiveWindowShadowSize);
|
||||
// qWarning("deactivated, search restarted (1)");
|
||||
inactiveGroupMembers.append(*it);
|
||||
tmpGroupMembers.erase(it);
|
||||
it = tmpGroupMembers.begin(); // restart, search next client
|
||||
continue;
|
||||
}
|
||||
else // pot. client does not touch c, so we have to search if it touches some other activated client
|
||||
{
|
||||
bool found = false;
|
||||
for( ClientList::ConstIterator it2 = inactiveGroupMembers.begin(); it2 != inactiveGroupMembers.end(); it2++ )
|
||||
{
|
||||
if ((*it2) != this && (*it2) != (*it) && (*it)->touches(*it2))
|
||||
{
|
||||
// qWarning("found client touches other inactive client");
|
||||
if( (*it)->ruleOpacityInactive() )
|
||||
(*it)->setOpacity((*it)->ruleOpacityInactive() < 0xFFFFFFFF, (*it)->ruleOpacityInactive());
|
||||
else
|
||||
(*it)->setOpacity(options->translucentInactiveWindows && !((*it)->keepAbove() && options->keepAboveAsActive), options->inactiveWindowOpacity);
|
||||
(*it)->setShadowSize(options->inactiveWindowShadowSize);
|
||||
// qWarning("deactivated, search restarted (2)");
|
||||
inactiveGroupMembers.append(*it);
|
||||
tmpGroupMembers.erase(it);
|
||||
it = tmpGroupMembers.begin(); // reset potential client search
|
||||
found = true;
|
||||
break; // skip this loop
|
||||
}
|
||||
}
|
||||
if (found) continue;
|
||||
}
|
||||
}
|
||||
it++;
|
||||
}
|
||||
}
|
||||
else if (isNormalWindow())
|
||||
{
|
||||
for( ClientList::ConstIterator it = group()->members().begin(); it != group()->members().end(); it++ )
|
||||
if ((*it)->isUtility()) //don't deactivate dialogs...
|
||||
if( (*it)->ruleOpacityInactive() )
|
||||
(*it)->setOpacity((*it)->ruleOpacityInactive() < 0xFFFFFFFF, (*it)->ruleOpacityInactive());
|
||||
else
|
||||
(*it)->setOpacity(options->translucentInactiveWindows && !((*it)->keepAbove() && options->keepAboveAsActive), options->inactiveWindowOpacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client::updateShadowSize()
|
||||
// extra syncscreen flag allows to avoid double syncs when active state changes (as it will usually change for two windows)
|
||||
{
|
||||
if (!(isNormalWindow() || isDialog() || isUtility() ))
|
||||
return;
|
||||
if (isActive())
|
||||
setShadowSize(options->activeWindowShadowSize);
|
||||
else
|
||||
setShadowSize(options->inactiveWindowShadowSize);
|
||||
}
|
||||
|
||||
double Client::opacity() const
|
||||
uint Client::ruleOpacityInactive()
|
||||
{
|
||||
if( info->opacity() == 0xffffffff )
|
||||
return 1.0;
|
||||
return info->opacity() * 1.0 / 0xffffffff;
|
||||
return rule_opacity_inactive;// != 0 ;
|
||||
}
|
||||
|
||||
void Client::setOpacity( double opacity )
|
||||
uint Client::ruleOpacityActive()
|
||||
{
|
||||
opacity = qBound( 0.0, opacity, 1.0 );
|
||||
info->setOpacity( static_cast< unsigned long >( opacity * 0xffffffff ));
|
||||
// we'll react on PropertyNotify
|
||||
return rule_opacity_active;// != 0;
|
||||
}
|
||||
|
||||
bool Client::getWindowOpacity() //query translucency settings from X, returns true if window opacity is set
|
||||
{
|
||||
unsigned char *data = 0;
|
||||
Atom actual;
|
||||
int format, result;
|
||||
unsigned long n, left;
|
||||
result = XGetWindowProperty(QX11Info::display(), window(), atoms->net_wm_window_opacity, 0L, 1L, False, XA_CARDINAL, &actual, &format, &n, &left, /*(unsigned char **)*/ &data);
|
||||
if (result == Success && data != None && format == 32 )
|
||||
{
|
||||
opacity_ = *reinterpret_cast< long* >( data );
|
||||
custom_opacity = true;
|
||||
// setOpacity(opacity_ < 0xFFFFFFFF, opacity_);
|
||||
XFree ((char*)data);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Client::setCustomOpacityFlag(bool custom)
|
||||
{
|
||||
custom_opacity = custom;
|
||||
}
|
||||
|
||||
uint Client::opacity()
|
||||
{
|
||||
return opacity_;
|
||||
}
|
||||
|
||||
void Client::debug( kdbgstream& stream ) const
|
||||
int Client::opacityPercentage()
|
||||
{
|
||||
stream << "\'ID:" << window() << ";WMCLASS:" << resourceClass() << ":" << resourceName() << ";Caption:" << caption() << "\'";
|
||||
return int(100*((double)opacity_/0xffffffff));
|
||||
}
|
||||
|
||||
bool Client::touches(const Client* c)
|
||||
// checks if this client borders c, needed to test beep media player window state
|
||||
{
|
||||
if (y() == c->y() + c->height()) // this bottom to c
|
||||
return true;
|
||||
if (y() + height() == c->y()) // this top to c
|
||||
return true;
|
||||
if (x() == c->x() + c->width()) // this right to c
|
||||
return true;
|
||||
if (x() + width() == c->x()) // this left to c
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Client::setDecoHashProperty(uint topHeight, uint rightWidth, uint bottomHeight, uint leftWidth)
|
||||
{
|
||||
long data = (topHeight < 255 ? topHeight : 255) << 24 |
|
||||
(rightWidth < 255 ? rightWidth : 255) << 16 |
|
||||
(bottomHeight < 255 ? bottomHeight : 255) << 8 |
|
||||
(leftWidth < 255 ? leftWidth : 255);
|
||||
XChangeProperty(QX11Info::display(), frameId(), atoms->net_wm_window_decohash, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &data, 1L);
|
||||
}
|
||||
|
||||
void Client::unsetDecoHashProperty()
|
||||
{
|
||||
XDeleteProperty( QX11Info::display(), frameId(), atoms->net_wm_window_decohash);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
kdbgstream& operator<<( kdbgstream& stream, const Client* cl )
|
||||
{
|
||||
if( cl == NULL )
|
||||
return stream << "\'NULL_CLIENT\'";
|
||||
return stream << "\'ID:" << cl->window() << ";WMCLASS:" << cl->resourceClass() << ":" << cl->resourceName() << ";Caption:" << cl->caption() << "\'";
|
||||
}
|
||||
kdbgstream& operator<<( kdbgstream& stream, const ClientList& list )
|
||||
{
|
||||
stream << "LIST:(";
|
||||
bool first = true;
|
||||
for( ClientList::ConstIterator it = list.begin();
|
||||
it != list.end();
|
||||
++it )
|
||||
{
|
||||
if( !first )
|
||||
stream << ":";
|
||||
first = false;
|
||||
stream << *it;
|
||||
}
|
||||
stream << ")";
|
||||
return stream;
|
||||
}
|
||||
kdbgstream& operator<<( kdbgstream& stream, const ConstClientList& list )
|
||||
{
|
||||
stream << "LIST:(";
|
||||
bool first = true;
|
||||
for( ConstClientList::ConstIterator it = list.begin();
|
||||
it != list.end();
|
||||
++it )
|
||||
{
|
||||
if( !first )
|
||||
stream << ":";
|
||||
first = false;
|
||||
stream << *it;
|
||||
}
|
||||
stream << ")";
|
||||
return stream;
|
||||
}
|
||||
#endif
|
||||
|
||||
QPixmap * kwin_get_menu_pix_hack()
|
||||
{
|
||||
|
|
102
geometry.cpp
102
geometry.cpp
|
@ -28,7 +28,6 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include "notifications.h"
|
||||
#include "geometrytip.h"
|
||||
#include "rules.h"
|
||||
#include "effects.h"
|
||||
#include <QX11Info>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
|
@ -634,18 +633,18 @@ void Workspace::updateTopMenuGeometry( Client* c )
|
|||
if( c != NULL )
|
||||
{
|
||||
XEvent ev;
|
||||
ev.xclient.display = display();
|
||||
ev.xclient.display = QX11Info::display();
|
||||
ev.xclient.type = ClientMessage;
|
||||
ev.xclient.window = c->window();
|
||||
static Atom msg_type_atom = XInternAtom( display(), "_KDE_TOPMENU_MINSIZE", False );
|
||||
static Atom msg_type_atom = XInternAtom( QX11Info::display(), "_KDE_TOPMENU_MINSIZE", False );
|
||||
ev.xclient.message_type = msg_type_atom;
|
||||
ev.xclient.format = 32;
|
||||
ev.xclient.data.l[0] = xTime();
|
||||
ev.xclient.data.l[0] = QX11Info::appTime();
|
||||
ev.xclient.data.l[1] = topmenu_space->width();
|
||||
ev.xclient.data.l[2] = topmenu_space->height();
|
||||
ev.xclient.data.l[3] = 0;
|
||||
ev.xclient.data.l[4] = 0;
|
||||
XSendEvent( display(), c->window(), False, NoEventMask, &ev );
|
||||
XSendEvent( QX11Info::display(), c->window(), False, NoEventMask, &ev );
|
||||
KWin::setStrut( c->window(), 0, 0, topmenu_height, 0 ); // so that kicker etc. know
|
||||
c->checkWorkspacePosition();
|
||||
return;
|
||||
|
@ -781,25 +780,25 @@ NETExtendedStrut Client::strut() const
|
|||
{
|
||||
ext.left_width = str.left;
|
||||
ext.left_start = 0;
|
||||
ext.left_end = displayHeight();
|
||||
ext.left_end = XDisplayHeight( QX11Info::display(), DefaultScreen( QX11Info::display()));
|
||||
}
|
||||
if( str.right != 0 )
|
||||
{
|
||||
ext.right_width = str.right;
|
||||
ext.right_start = 0;
|
||||
ext.right_end = displayHeight();
|
||||
ext.right_end = XDisplayHeight( QX11Info::display(), DefaultScreen( QX11Info::display()));
|
||||
}
|
||||
if( str.top != 0 )
|
||||
{
|
||||
ext.top_width = str.top;
|
||||
ext.top_start = 0;
|
||||
ext.top_end = displayWidth();
|
||||
ext.top_end = XDisplayWidth( QX11Info::display(), DefaultScreen( QX11Info::display()));
|
||||
}
|
||||
if( str.bottom != 0 )
|
||||
{
|
||||
ext.bottom_width = str.bottom;
|
||||
ext.bottom_start = 0;
|
||||
ext.bottom_end = displayWidth();
|
||||
ext.bottom_end = XDisplayWidth( QX11Info::display(), DefaultScreen( QX11Info::display()));
|
||||
}
|
||||
}
|
||||
return ext;
|
||||
|
@ -1197,7 +1196,7 @@ QSize Client::sizeForClientSize( const QSize& wsize, Sizemode mode, bool noframe
|
|||
void Client::getWmNormalHints()
|
||||
{
|
||||
long msize;
|
||||
if (XGetWMNormalHints(display(), window(), &xSizeHint, &msize) == 0 )
|
||||
if (XGetWMNormalHints(QX11Info::display(), window(), &xSizeHint, &msize) == 0 )
|
||||
xSizeHint.flags = 0;
|
||||
// set defined values for the fields, even if they're not in flags
|
||||
|
||||
|
@ -1299,7 +1298,7 @@ void Client::sendSyntheticConfigureNotify()
|
|||
c.border_width = 0;
|
||||
c.above = None;
|
||||
c.override_redirect = 0;
|
||||
XSendEvent( display(), c.event, true, StructureNotifyMask, (XEvent*)&c );
|
||||
XSendEvent( QX11Info::display(), c.event, true, StructureNotifyMask, (XEvent*)&c );
|
||||
}
|
||||
|
||||
const QPoint Client::calculateGravitation( bool invert, int gravity ) const
|
||||
|
@ -1658,11 +1657,9 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force )
|
|||
{
|
||||
client_size = QSize( w - border_left - border_right, h - border_top - border_bottom );
|
||||
}
|
||||
if( force == NormalGeometrySet && geom == QRect( x, y, w, h ))
|
||||
if( force == NormalGeometrySet && frame_geometry == QRect( x, y, w, h ))
|
||||
return;
|
||||
// TODO add damage only if not obscured
|
||||
workspace()->addDamage( this, geometry()); // TODO cache the previous real geometry
|
||||
geom = QRect( x, y, w, h );
|
||||
frame_geometry = QRect( x, y, w, h );
|
||||
updateWorkareaDiffs();
|
||||
if( postpone_geometry_updates != 0 )
|
||||
{
|
||||
|
@ -1670,24 +1667,21 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force )
|
|||
return;
|
||||
}
|
||||
resizeDecoration( QSize( w, h ));
|
||||
XMoveResizeWindow( display(), frameId(), x, y, w, h );
|
||||
XMoveResizeWindow( QX11Info::display(), frameId(), x, y, w, h );
|
||||
// resizeDecoration( QSize( w, h ));
|
||||
if( !isShade())
|
||||
{
|
||||
QSize cs = clientSize();
|
||||
XMoveResizeWindow( display(), wrapperId(), clientPos().x(), clientPos().y(),
|
||||
XMoveResizeWindow( QX11Info::display(), wrapperId(), clientPos().x(), clientPos().y(),
|
||||
cs.width(), cs.height());
|
||||
XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height());
|
||||
XMoveResizeWindow( QX11Info::display(), window(), 0, 0, cs.width(), cs.height());
|
||||
}
|
||||
if( shape())
|
||||
updateShape();
|
||||
updateShape();
|
||||
// SELI TODO won't this be too expensive?
|
||||
updateWorkareaDiffs();
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
checkMaximizeGeometry();
|
||||
resetWindowPixmap();
|
||||
workspace()->addDamage( this, geometry());
|
||||
}
|
||||
|
||||
void Client::plainResize( int w, int h, ForceGeometry_t force )
|
||||
|
@ -1717,10 +1711,9 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
|
|||
kDebug() << "forced size fail:" << QSize( w,h ) << ":" << rules()->checkSize( QSize( w, h )) << endl;
|
||||
kDebug() << kBacktrace() << endl;
|
||||
}
|
||||
if( force == NormalGeometrySet && geom.size() == QSize( w, h ))
|
||||
if( force == NormalGeometrySet && frame_geometry.size() == QSize( w, h ))
|
||||
return;
|
||||
workspace()->addDamage( this, geometry()); // TODO cache the previous real geometry
|
||||
geom.setSize( QSize( w, h ));
|
||||
frame_geometry.setSize( QSize( w, h ));
|
||||
updateWorkareaDiffs();
|
||||
if( postpone_geometry_updates != 0 )
|
||||
{
|
||||
|
@ -1728,23 +1721,20 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
|
|||
return;
|
||||
}
|
||||
resizeDecoration( QSize( w, h ));
|
||||
XResizeWindow( display(), frameId(), w, h );
|
||||
XResizeWindow( QX11Info::display(), frameId(), w, h );
|
||||
// resizeDecoration( QSize( w, h ));
|
||||
if( !isShade())
|
||||
{
|
||||
QSize cs = clientSize();
|
||||
XMoveResizeWindow( display(), wrapperId(), clientPos().x(), clientPos().y(),
|
||||
XMoveResizeWindow( QX11Info::display(), wrapperId(), clientPos().x(), clientPos().y(),
|
||||
cs.width(), cs.height());
|
||||
XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height());
|
||||
XMoveResizeWindow( QX11Info::display(), window(), 0, 0, cs.width(), cs.height());
|
||||
}
|
||||
if( shape())
|
||||
updateShape();
|
||||
updateShape();
|
||||
updateWorkareaDiffs();
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
checkMaximizeGeometry();
|
||||
resetWindowPixmap();
|
||||
workspace()->addDamage( this, geometry());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1752,23 +1742,22 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
|
|||
*/
|
||||
void Client::move( int x, int y, ForceGeometry_t force )
|
||||
{
|
||||
if( force == NormalGeometrySet && geom.topLeft() == QPoint( x, y ))
|
||||
if( force == NormalGeometrySet && frame_geometry.topLeft() == QPoint( x, y ))
|
||||
return;
|
||||
workspace()->addDamage( this, geometry()); // TODO cache the previous real geometry
|
||||
geom.moveTopLeft( QPoint( x, y ));
|
||||
frame_geometry.moveTopLeft( QPoint( x, y ));
|
||||
updateWorkareaDiffs();
|
||||
if( postpone_geometry_updates != 0 )
|
||||
{
|
||||
pending_geometry_update = true;
|
||||
return;
|
||||
}
|
||||
XMoveWindow( display(), frameId(), x, y );
|
||||
XMoveWindow( QX11Info::display(), frameId(), x, y );
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
checkMaximizeGeometry();
|
||||
workspace()->addDamage( this, geometry());
|
||||
}
|
||||
|
||||
|
||||
void Client::postponeGeometryUpdates( bool postpone )
|
||||
{
|
||||
if( postpone )
|
||||
|
@ -2231,18 +2220,18 @@ bool Client::startMoveResize()
|
|||
// (http://lists.kde.org/?t=107302193400001&r=1&w=2)
|
||||
XSetWindowAttributes attrs;
|
||||
QRect r = workspace()->clientArea( FullArea, this );
|
||||
move_resize_grab_window = XCreateWindow( display(), workspace()->rootWin(), r.x(), r.y(),
|
||||
move_resize_grab_window = XCreateWindow( QX11Info::display(), workspace()->rootWin(), r.x(), r.y(),
|
||||
r.width(), r.height(), 0, CopyFromParent, InputOnly, CopyFromParent, 0, &attrs );
|
||||
XMapRaised( display(), move_resize_grab_window );
|
||||
if( XGrabPointer( display(), move_resize_grab_window, False,
|
||||
XMapRaised( QX11Info::display(), move_resize_grab_window );
|
||||
if( XGrabPointer( QX11Info::display(), move_resize_grab_window, False,
|
||||
ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask,
|
||||
GrabModeAsync, GrabModeAsync, None, cursor.handle(), xTime() ) == Success )
|
||||
GrabModeAsync, GrabModeAsync, None, cursor.handle(), QX11Info::appTime() ) == Success )
|
||||
has_grab = true;
|
||||
if( XGrabKeyboard( display(), frameId(), False, GrabModeAsync, GrabModeAsync, xTime() ) == Success )
|
||||
if( XGrabKeyboard( QX11Info::display(), frameId(), False, GrabModeAsync, GrabModeAsync, QX11Info::appTime() ) == Success )
|
||||
has_grab = true;
|
||||
if( !has_grab ) // at least one grab is necessary in order to be able to finish move/resize
|
||||
{
|
||||
XDestroyWindow( display(), move_resize_grab_window );
|
||||
XDestroyWindow( QX11Info::display(), move_resize_grab_window );
|
||||
move_resize_grab_window = None;
|
||||
return false;
|
||||
}
|
||||
|
@ -2252,6 +2241,13 @@ bool Client::startMoveResize()
|
|||
workspace()->setClientIsMoving(this);
|
||||
initialMoveResizeGeom = moveResizeGeom = geometry();
|
||||
checkUnrestrictedMoveResize();
|
||||
// rule out non opaque windows from useless translucency settings, maybe resizes?
|
||||
if ((isResize() && options->removeShadowsOnResize) || (isMove() && options->removeShadowsOnMove))
|
||||
setShadowSize(0);
|
||||
if (rules()->checkMoveResizeMode( options->moveMode ) == Options::Opaque){
|
||||
savedOpacity_ = opacity_;
|
||||
setOpacity(options->translucentMovingWindows, options->movingWindowOpacity);
|
||||
}
|
||||
if ( ( isMove() && rules()->checkMoveResizeMode( options->moveMode ) != Options::Opaque )
|
||||
|| ( isResize() && rules()->checkMoveResizeMode( options->resizeMode ) != Options::Opaque ) )
|
||||
{
|
||||
|
@ -2266,8 +2262,6 @@ bool Client::startMoveResize()
|
|||
// not needed anymore? kapp->installEventFilter( eater );
|
||||
}
|
||||
Notify::raise( isResize() ? Notify::ResizeStart : Notify::MoveStart );
|
||||
if( effects )
|
||||
effects->windowUserMovedResized( this, true, false );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2281,12 +2275,15 @@ void Client::finishMoveResize( bool cancel )
|
|||
checkMaximizeGeometry();
|
||||
// FRAME update();
|
||||
Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd );
|
||||
if( effects )
|
||||
effects->windowUserMovedResized( this, false, true );
|
||||
}
|
||||
|
||||
void Client::leaveMoveResize()
|
||||
{
|
||||
// rule out non opaque windows from useless translucency settings, maybe resizes?
|
||||
if (rules()->checkMoveResizeMode( options->moveMode ) == Options::Opaque)
|
||||
setOpacity(true, savedOpacity_);
|
||||
if ((isResize() && options->removeShadowsOnResize) || (isMove() && options->removeShadowsOnMove))
|
||||
updateShadowSize();
|
||||
clearbound();
|
||||
if (geometryTip)
|
||||
{
|
||||
|
@ -2297,9 +2294,9 @@ void Client::leaveMoveResize()
|
|||
if ( ( isMove() && rules()->checkMoveResizeMode( options->moveMode ) != Options::Opaque )
|
||||
|| ( isResize() && rules()->checkMoveResizeMode( options->resizeMode ) != Options::Opaque ) )
|
||||
ungrabXServer();
|
||||
XUngrabKeyboard( display(), xTime() );
|
||||
XUngrabPointer( display(), xTime() );
|
||||
XDestroyWindow( display(), move_resize_grab_window );
|
||||
XUngrabKeyboard( QX11Info::display(), QX11Info::appTime() );
|
||||
XUngrabPointer( QX11Info::display(), QX11Info::appTime() );
|
||||
XDestroyWindow( QX11Info::display(), move_resize_grab_window );
|
||||
move_resize_grab_window = None;
|
||||
workspace()->setClientIsMoving(0);
|
||||
if( move_faked_activity )
|
||||
|
@ -2545,9 +2542,8 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root )
|
|||
} // so the geometry tip will be painted above the outline
|
||||
}
|
||||
if ( isMove() )
|
||||
workspace()->clientMoved(globalPos, xTime());
|
||||
if( effects )
|
||||
effects->windowUserMovedResized( this, false, false );
|
||||
workspace()->clientMoved(globalPos, QX11Info::appTime());
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
|
65
manage.cpp
65
manage.cpp
|
@ -38,29 +38,22 @@ bool Client::manage( Window w, bool isMapped )
|
|||
{
|
||||
StackingUpdatesBlocker stacking_blocker( workspace());
|
||||
|
||||
grabXServer();
|
||||
|
||||
XWindowAttributes attr;
|
||||
if( !XGetWindowAttributes(display(), w, &attr))
|
||||
{
|
||||
ungrabXServer();
|
||||
if( !XGetWindowAttributes(QX11Info::display(), w, &attr))
|
||||
return false;
|
||||
}
|
||||
|
||||
grabXServer();
|
||||
|
||||
// from this place on, manage() mustn't return false
|
||||
postpone_geometry_updates = 1;
|
||||
pending_geometry_update = true; // force update when finishing with geometry changes
|
||||
|
||||
embedClient( w, attr );
|
||||
|
||||
vis = attr.visual;
|
||||
|
||||
setupCompositing();
|
||||
|
||||
// SELI order all these things in some sane manner
|
||||
|
||||
bool init_minimize = false;
|
||||
XWMHints * hints = XGetWMHints(display(), w );
|
||||
XWMHints * hints = XGetWMHints(QX11Info::display(), w );
|
||||
if (hints && (hints->flags & StateHint) && hints->initial_state == IconicState)
|
||||
init_minimize = true;
|
||||
if (hints)
|
||||
|
@ -84,15 +77,14 @@ bool Client::manage( Window w, bool isMapped )
|
|||
NET::WM2UserTime |
|
||||
NET::WM2StartupId |
|
||||
NET::WM2ExtendedStrut |
|
||||
NET::WM2Opacity |
|
||||
0;
|
||||
|
||||
info = new WinInfo( this, display(), client, rootWindow(), properties, 2 );
|
||||
info = new WinInfo( this, QX11Info::display(), client, QX11Info::appRootWindow(), properties, 2 );
|
||||
|
||||
cmap = attr.colormap;
|
||||
|
||||
XClassHint classHint;
|
||||
if ( XGetClassHint( display(), client, &classHint ) )
|
||||
if ( XGetClassHint( QX11Info::display(), client, &classHint ) )
|
||||
{
|
||||
// Qt3.2 and older had this all lowercase, Qt3.3 capitalized resource class
|
||||
// force lowercase, so that workarounds listing resource classes still work
|
||||
|
@ -114,6 +106,7 @@ bool Client::manage( Window w, bool isMapped )
|
|||
setCaption( cap_normal, true );
|
||||
|
||||
detectNoBorder();
|
||||
detectShapable();
|
||||
fetchIconicName();
|
||||
getWMHints(); // needs to be done before readTransient() because of reading the group
|
||||
modal = ( info->state() & NET::Modal ) != 0; // needs to be valid before handling groups
|
||||
|
@ -150,6 +143,8 @@ bool Client::manage( Window w, bool isMapped )
|
|||
if( rules()->checkNoBorder( false, !isMapped ))
|
||||
setUserNoBorder( true );
|
||||
|
||||
checkAndSetInitialRuledOpacity();
|
||||
|
||||
// initial desktop placement
|
||||
if ( session )
|
||||
{
|
||||
|
@ -321,10 +316,9 @@ bool Client::manage( Window w, bool isMapped )
|
|||
if(( !isSpecialWindow() || isToolbar()) && isMovable())
|
||||
keepInArea( area, partial_keep_in_area );
|
||||
|
||||
if( Extensions::shapeAvailable())
|
||||
XShapeSelectInput( display(), window(), ShapeNotifyMask );
|
||||
if ( (is_shape = hasShape( window())) )
|
||||
updateShape();
|
||||
XShapeSelectInput( QX11Info::display(), window(), ShapeNotifyMask );
|
||||
is_shape = Shape::hasShape( window());
|
||||
updateShape();
|
||||
|
||||
//CT extra check for stupid jdk 1.3.1. But should make sense in general
|
||||
// if client has initial state set to Iconic and is transient with a parent
|
||||
|
@ -437,7 +431,7 @@ bool Client::manage( Window w, bool isMapped )
|
|||
|
||||
// this should avoid flicker, because real restacking is done
|
||||
// only after manage() finishes because of blocking, but the window is shown sooner
|
||||
XLowerWindow( display(), frameId());
|
||||
XLowerWindow( QX11Info::display(), frameId());
|
||||
if( session && session->stackingOrder != -1 )
|
||||
{
|
||||
sm_stacking_order = session->stackingOrder;
|
||||
|
@ -509,9 +503,9 @@ bool Client::manage( Window w, bool isMapped )
|
|||
|
||||
if( user_time == CurrentTime || user_time == -1U ) // no known user time, set something old
|
||||
{
|
||||
user_time = xTime() - 1000000;
|
||||
user_time = QX11Info::appTime() - 1000000;
|
||||
if( user_time == CurrentTime || user_time == -1U ) // let's be paranoid
|
||||
user_time = xTime() - 1000000 + 10;
|
||||
user_time = QX11Info::appTime() - 1000000 + 10;
|
||||
}
|
||||
|
||||
updateWorkareaDiffs();
|
||||
|
@ -519,7 +513,7 @@ bool Client::manage( Window w, bool isMapped )
|
|||
// sendSyntheticConfigureNotify(); done when setting mapping state
|
||||
|
||||
delete session;
|
||||
|
||||
|
||||
ungrabXServer();
|
||||
|
||||
client_rules.discardTemporary();
|
||||
|
@ -537,35 +531,34 @@ bool Client::manage( Window w, bool isMapped )
|
|||
void Client::embedClient( Window w, const XWindowAttributes &attr )
|
||||
{
|
||||
assert( client == None );
|
||||
assert( frameId() == None );
|
||||
assert( frame == None );
|
||||
assert( wrapper == None );
|
||||
client = w;
|
||||
// we don't want the window to be destroyed when we are destroyed
|
||||
XAddToSaveSet( display(), client );
|
||||
XSelectInput( display(), client, NoEventMask );
|
||||
XUnmapWindow( display(), client );
|
||||
XAddToSaveSet( QX11Info::display(), client );
|
||||
XSelectInput( QX11Info::display(), client, NoEventMask );
|
||||
XUnmapWindow( QX11Info::display(), client );
|
||||
XWindowChanges wc; // set the border width to 0
|
||||
wc.border_width = 0; // TODO possibly save this, and also use it for initial configuring of the window
|
||||
XConfigureWindow( display(), client, CWBorderWidth, &wc );
|
||||
XConfigureWindow( QX11Info::display(), client, CWBorderWidth, &wc );
|
||||
|
||||
XSetWindowAttributes swa;
|
||||
swa.colormap = attr.colormap;
|
||||
swa.background_pixmap = None;
|
||||
swa.border_pixel = 0;
|
||||
|
||||
Window frame = XCreateWindow( display(), rootWindow(), 0, 0, 1, 1, 0,
|
||||
frame = XCreateWindow( QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0,
|
||||
attr.depth, InputOutput, attr.visual,
|
||||
CWColormap | CWBackPixmap | CWBorderPixel, &swa );
|
||||
setHandle( frame );
|
||||
wrapper = XCreateWindow( display(), frame, 0, 0, 1, 1, 0,
|
||||
wrapper = XCreateWindow( QX11Info::display(), frame, 0, 0, 1, 1, 0,
|
||||
attr.depth, InputOutput, attr.visual,
|
||||
CWColormap | CWBackPixmap | CWBorderPixel, &swa );
|
||||
|
||||
XDefineCursor( display(), frame, QCursor( Qt::ArrowCursor ).handle());
|
||||
XDefineCursor( QX11Info::display(), frame, QCursor( Qt::ArrowCursor ).handle());
|
||||
// some apps are stupid and don't define their own cursor - set the arrow one for them
|
||||
XDefineCursor( display(), wrapper, QCursor( Qt::ArrowCursor ).handle());
|
||||
XReparentWindow( display(), client, wrapper, 0, 0 );
|
||||
XSelectInput( display(), frame,
|
||||
XDefineCursor( QX11Info::display(), wrapper, QCursor( Qt::ArrowCursor ).handle());
|
||||
XReparentWindow( QX11Info::display(), client, wrapper, 0, 0 );
|
||||
XSelectInput( QX11Info::display(), frame,
|
||||
KeyPressMask | KeyReleaseMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
KeymapStateMask |
|
||||
|
@ -577,8 +570,8 @@ void Client::embedClient( Window w, const XWindowAttributes &attr )
|
|||
PropertyChangeMask |
|
||||
StructureNotifyMask | SubstructureRedirectMask |
|
||||
VisibilityChangeMask );
|
||||
XSelectInput( display(), wrapper, ClientWinMask | SubstructureNotifyMask );
|
||||
XSelectInput( display(), client,
|
||||
XSelectInput( QX11Info::display(), wrapper, ClientWinMask | SubstructureNotifyMask );
|
||||
XSelectInput( QX11Info::display(), client,
|
||||
FocusChangeMask |
|
||||
PropertyChangeMask |
|
||||
ColormapChangeMask |
|
||||
|
|
130
utils.cpp
130
utils.cpp
|
@ -30,7 +30,6 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include <X11/extensions/shape.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <QX11Info>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "atoms.h"
|
||||
|
@ -43,54 +42,41 @@ namespace KWinInternal
|
|||
|
||||
#ifndef KCMRULES
|
||||
|
||||
bool Extensions::has_shape = 0;
|
||||
int Extensions::shape_event_base = 0;
|
||||
bool Extensions::has_damage = 0;
|
||||
int Extensions::damage_event_base = 0;
|
||||
bool Extensions::has_composite = 0;
|
||||
bool Extensions::has_fixes = 0;
|
||||
// used to store the return values of
|
||||
// XShapeQueryExtension.
|
||||
// Necessary since shaped window are an extension to X
|
||||
int Shape::kwin_shape_version = 0;
|
||||
int Shape::kwin_shape_event = 0;
|
||||
|
||||
void Extensions::init()
|
||||
// does the window w need a shape combine mask around it?
|
||||
bool Shape::hasShape( WId w)
|
||||
{
|
||||
int xws, yws, xbs, ybs;
|
||||
unsigned int wws, hws, wbs, hbs;
|
||||
int boundingShaped = 0, clipShaped = 0;
|
||||
if (!available())
|
||||
return false;
|
||||
XShapeQueryExtents(QX11Info::display(), w,
|
||||
&boundingShaped, &xws, &yws, &wws, &hws,
|
||||
&clipShaped, &xbs, &ybs, &wbs, &hbs);
|
||||
return boundingShaped != 0;
|
||||
}
|
||||
|
||||
int Shape::shapeEvent()
|
||||
{
|
||||
return kwin_shape_event;
|
||||
}
|
||||
|
||||
void Shape::init()
|
||||
{
|
||||
kwin_shape_version = 0;
|
||||
int dummy;
|
||||
has_shape = XShapeQueryExtension( display(), &shape_event_base, &dummy);
|
||||
#ifdef HAVE_XDAMAGE
|
||||
has_damage = XDamageQueryExtension( display(), &damage_event_base, &dummy );
|
||||
#else
|
||||
has_damage = false;
|
||||
#endif
|
||||
#ifdef HAVE_XCOMPOSITE
|
||||
has_composite = XCompositeQueryExtension( display(), &dummy, &dummy );
|
||||
if( has_composite )
|
||||
{
|
||||
int major = 0;
|
||||
int minor = 2;
|
||||
XCompositeQueryVersion( display(), &major, &minor );
|
||||
if( major == 0 && minor < 2 )
|
||||
has_composite = false;
|
||||
}
|
||||
#else
|
||||
has_composite = false;
|
||||
#endif
|
||||
#ifdef HAVE_XFIXES
|
||||
has_fixes = XFixesQueryExtension( display(), &dummy, &dummy );
|
||||
#else
|
||||
has_fixes = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int Extensions::shapeNotifyEvent()
|
||||
{
|
||||
return shape_event_base + ShapeNotify;
|
||||
}
|
||||
|
||||
int Extensions::damageNotifyEvent()
|
||||
{
|
||||
#ifdef HAVE_XDAMAGE
|
||||
return damage_event_base + XDamageNotify;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
if( !XShapeQueryExtension( QX11Info::display(), &kwin_shape_event, &dummy ))
|
||||
return;
|
||||
int major, minor;
|
||||
if( !XShapeQueryVersion( QX11Info::display(), &major, &minor ))
|
||||
return;
|
||||
kwin_shape_version = major * 16 + minor;
|
||||
}
|
||||
|
||||
void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move,
|
||||
|
@ -101,7 +87,7 @@ void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move,
|
|||
unsigned long length, after;
|
||||
unsigned char* data;
|
||||
MwmHints* hints = 0;
|
||||
if ( XGetWindowProperty( display(), w, atoms->motif_wm_hints, 0, 5,
|
||||
if ( XGetWindowProperty( QX11Info::display(), w, atoms->motif_wm_hints, 0, 5,
|
||||
false, atoms->motif_wm_hints, &type, &format,
|
||||
&length, &after, &data ) == Success )
|
||||
{
|
||||
|
@ -154,10 +140,10 @@ KWinSelectionOwner::KWinSelectionOwner( int screen_P )
|
|||
Atom KWinSelectionOwner::make_selection_atom( int screen_P )
|
||||
{
|
||||
if( screen_P < 0 )
|
||||
screen_P = DefaultScreen( display());
|
||||
screen_P = DefaultScreen( QX11Info::display());
|
||||
char tmp[ 30 ];
|
||||
sprintf( tmp, "WM_S%d", screen_P );
|
||||
return XInternAtom( display(), tmp, False );
|
||||
return XInternAtom( QX11Info::display(), tmp, False );
|
||||
}
|
||||
|
||||
void KWinSelectionOwner::getAtoms()
|
||||
|
@ -168,7 +154,7 @@ void KWinSelectionOwner::getAtoms()
|
|||
Atom atoms[ 1 ];
|
||||
const char* const names[] =
|
||||
{ "VERSION" };
|
||||
XInternAtoms( display(), const_cast< char** >( names ), 1, False, atoms );
|
||||
XInternAtoms( QX11Info::display(), const_cast< char** >( names ), 1, False, atoms );
|
||||
xa_version = atoms[ 0 ];
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +164,7 @@ void KWinSelectionOwner::replyTargets( Atom property_P, Window requestor_P )
|
|||
KSelectionOwner::replyTargets( property_P, requestor_P );
|
||||
Atom atoms[ 1 ] = { xa_version };
|
||||
// PropModeAppend !
|
||||
XChangeProperty( display(), requestor_P, property_P, XA_ATOM, 32, PropModeAppend,
|
||||
XChangeProperty( QX11Info::display(), requestor_P, property_P, XA_ATOM, 32, PropModeAppend,
|
||||
reinterpret_cast< unsigned char* >( atoms ), 1 );
|
||||
}
|
||||
|
||||
|
@ -187,7 +173,7 @@ bool KWinSelectionOwner::genericReply( Atom target_P, Atom property_P, Window re
|
|||
if( target_P == xa_version )
|
||||
{
|
||||
long version[] = { 2, 0 };
|
||||
XChangeProperty( display(), requestor_P, property_P, XA_INTEGER, 32,
|
||||
XChangeProperty( QX11Info::display(), requestor_P, property_P, XA_INTEGER, 32,
|
||||
PropModeReplace, reinterpret_cast< unsigned char* >( &version ), 2 );
|
||||
}
|
||||
else
|
||||
|
@ -207,7 +193,7 @@ QByteArray getStringProperty(WId w, Atom prop, char separator)
|
|||
unsigned char *data = 0;
|
||||
QByteArray result = "";
|
||||
KXErrorHandler handler; // ignore errors
|
||||
status = XGetWindowProperty( display(), w, prop, 0, 10000,
|
||||
status = XGetWindowProperty( QX11Info::display(), w, prop, 0, 10000,
|
||||
false, XA_STRING, &type, &format,
|
||||
&nitems, &extra, &data );
|
||||
if ( status == Success)
|
||||
|
@ -262,8 +248,8 @@ static Bool update_x_time_predicate( Display*, XEvent* event, XPointer )
|
|||
}
|
||||
|
||||
/*
|
||||
Updates xTime(). This used to simply fetch current timestamp from the server,
|
||||
but that can cause xTime() to be newer than timestamp of events that are
|
||||
Updates QX11Info::appTime(). This used to simply fetch current timestamp from the server,
|
||||
but that can cause QX11Info::appTime() to be newer than timestamp of events that are
|
||||
still in our events queue, thus e.g. making XSetInputFocus() caused by such
|
||||
event to be ignored. Therefore events queue is searched for first
|
||||
event with timestamp, and extra PropertyNotify is generated in order to make
|
||||
|
@ -275,20 +261,20 @@ void updateXTime()
|
|||
if ( !w )
|
||||
w = new QWidget;
|
||||
long data = 1;
|
||||
XChangeProperty(display(), w->winId(), atoms->kwin_running, atoms->kwin_running, 32,
|
||||
XChangeProperty(QX11Info::display(), w->winId(), atoms->kwin_running, atoms->kwin_running, 32,
|
||||
PropModeAppend, (unsigned char*) &data, 1);
|
||||
next_x_time = CurrentTime;
|
||||
XEvent dummy;
|
||||
XCheckIfEvent( display(), &dummy, update_x_time_predicate, NULL );
|
||||
XCheckIfEvent( QX11Info::display(), &dummy, update_x_time_predicate, NULL );
|
||||
if( next_x_time == CurrentTime )
|
||||
{
|
||||
XSync( display(), False );
|
||||
XCheckIfEvent( display(), &dummy, update_x_time_predicate, NULL );
|
||||
XSync( QX11Info::display(), False );
|
||||
XCheckIfEvent( QX11Info::display(), &dummy, update_x_time_predicate, NULL );
|
||||
}
|
||||
assert( next_x_time != CurrentTime );
|
||||
QX11Info::setAppTime( next_x_time );
|
||||
XEvent ev; // remove the PropertyNotify event from the events queue
|
||||
XWindowEvent( display(), w->winId(), PropertyChangeMask, &ev );
|
||||
XWindowEvent( QX11Info::display(), w->winId(), PropertyChangeMask, &ev );
|
||||
}
|
||||
|
||||
static int server_grab_count = 0;
|
||||
|
@ -296,7 +282,7 @@ static int server_grab_count = 0;
|
|||
void grabXServer()
|
||||
{
|
||||
if( ++server_grab_count == 1 )
|
||||
XGrabServer( display());
|
||||
XGrabServer( QX11Info::display());
|
||||
}
|
||||
|
||||
void ungrabXServer()
|
||||
|
@ -304,8 +290,8 @@ void ungrabXServer()
|
|||
assert( server_grab_count > 0 );
|
||||
if( --server_grab_count == 0 )
|
||||
{
|
||||
XUngrabServer( display());
|
||||
XFlush( display());
|
||||
XUngrabServer( QX11Info::display());
|
||||
XFlush( QX11Info::display());
|
||||
Notify::sendPendingEvents();
|
||||
}
|
||||
}
|
||||
|
@ -315,20 +301,6 @@ bool grabbedXServer()
|
|||
return server_grab_count > 0;
|
||||
}
|
||||
|
||||
kdbgstream& operator<<( kdbgstream& stream, RegionDebug r )
|
||||
{
|
||||
if( r.rr == None )
|
||||
return stream << "EMPTY";
|
||||
int num;
|
||||
XRectangle* rects = XFixesFetchRegion( display(), r.rr, &num );
|
||||
if( rects == NULL || num == 0 )
|
||||
return stream << "EMPTY";
|
||||
for( int i = 0;
|
||||
i < num;
|
||||
++i )
|
||||
stream << "[" << rects[ i ].x << "+" << rects[ i ].y << " " << rects[ i ].width << "x" << rects[ i ].height << "]";
|
||||
return stream;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool isLocalMachine( const QByteArray& host )
|
||||
|
@ -360,7 +332,7 @@ ShortcutDialog::ShortcutDialog( const KShortcut& cut )
|
|||
// make it a popup, so that it has the grab
|
||||
XSetWindowAttributes attrs;
|
||||
attrs.override_redirect = True;
|
||||
XChangeWindowAttributes( display(), winId(), CWOverrideRedirect, &attrs );
|
||||
XChangeWindowAttributes( QX11Info::display(), winId(), CWOverrideRedirect, &attrs );
|
||||
setWindowFlags( Qt::Popup );
|
||||
}
|
||||
|
||||
|
@ -395,6 +367,8 @@ void ShortcutDialog::accept()
|
|||
KShortcutDialog::accept();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifndef KCMRULES
|
||||
|
|
128
utils.h
128
utils.h
|
@ -12,43 +12,15 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#ifndef KWIN_UTILS_H
|
||||
#define KWIN_UTILS_H
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#ifdef HAVE_XCOMPOSITE
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#endif
|
||||
#ifdef HAVE_XDAMAGE
|
||||
#include <X11/extensions/Xdamage.h>
|
||||
#endif
|
||||
#ifdef HAVE_XFIXES
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#endif
|
||||
|
||||
#include <fixx11h.h>
|
||||
|
||||
#include <QWidget>
|
||||
#include <kmanagerselection.h>
|
||||
#include <netwm_def.h>
|
||||
#include <kshortcutdialog.h>
|
||||
#include <limits.h>
|
||||
#include <QX11Info>
|
||||
|
||||
namespace KWinInternal
|
||||
{
|
||||
|
||||
#ifndef HAVE_XDAMAGE
|
||||
typedef long Damage;
|
||||
struct XDamageNotifyEvent
|
||||
{
|
||||
};
|
||||
#endif
|
||||
#ifndef HAVE_XFIXES
|
||||
struct XserverRegion
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
|
||||
| NET::ToolbarMask | NET::MenuMask | NET::DialogMask /*| NET::OverrideMask*/ | NET::TopMenuMask
|
||||
| NET::UtilityMask | NET::SplashMask;
|
||||
|
@ -66,18 +38,12 @@ const long ClientWinMask = KeyPressMask | KeyReleaseMask |
|
|||
|
||||
const QPoint invalidPoint( INT_MIN, INT_MIN );
|
||||
|
||||
class Toplevel;
|
||||
class Client;
|
||||
class Unmanaged;
|
||||
class Group;
|
||||
class Options;
|
||||
|
||||
typedef QList< Toplevel* > ToplevelList;
|
||||
typedef QList< const Toplevel* > ConstToplevelList;
|
||||
typedef QList< Client* > ClientList;
|
||||
typedef QList< const Client* > ConstClientList;
|
||||
typedef QList< Unmanaged* > UnmanagedList;
|
||||
typedef QList< const Unmanaged* > ConstUnmanagedList;
|
||||
|
||||
typedef QList< Group* > GroupList;
|
||||
typedef QList< const Group* > ConstGroupList;
|
||||
|
@ -120,20 +86,6 @@ enum allowed_t { Allowed };
|
|||
// some enums to have more readable code, instead of using bools
|
||||
enum ForceGeometry_t { NormalGeometrySet, ForceGeometrySet };
|
||||
|
||||
|
||||
struct RegionDebug
|
||||
{
|
||||
RegionDebug( XserverRegion r ) : rr( r ) {}
|
||||
XserverRegion rr;
|
||||
};
|
||||
|
||||
#ifdef NDEBUG
|
||||
inline
|
||||
kndbgstream& operator<<( kndbgstream& stream, RegionDebug ) { return stream; }
|
||||
#else
|
||||
kdbgstream& operator<<( kdbgstream& stream, RegionDebug r );
|
||||
#endif
|
||||
|
||||
// Areas, mostly related to Xinerama
|
||||
enum clientAreaOption
|
||||
{
|
||||
|
@ -156,23 +108,18 @@ enum ShadeMode
|
|||
ShadeActivated // "shaded", but visible due to alt+tab to the window
|
||||
};
|
||||
|
||||
class Extensions
|
||||
class Shape
|
||||
{
|
||||
public:
|
||||
static bool available() { return kwin_shape_version > 0; }
|
||||
static int major() { return kwin_shape_version / 16; }
|
||||
static int minor() { return kwin_shape_version % 16; }
|
||||
static bool hasShape( WId w);
|
||||
static int shapeEvent();
|
||||
static void init();
|
||||
static bool shapeAvailable() { return has_shape; }
|
||||
static int shapeNotifyEvent();
|
||||
static bool damageAvailable() { return has_damage; }
|
||||
static int damageNotifyEvent();
|
||||
static bool compositeAvailable() { return has_composite; }
|
||||
static bool fixesAvailable() { return has_fixes; }
|
||||
private:
|
||||
static bool has_shape;
|
||||
static int shape_event_base;
|
||||
static bool has_damage;
|
||||
static int damage_event_base;
|
||||
static bool has_composite;
|
||||
static bool has_fixes;
|
||||
static int kwin_shape_version; // as 16*major+minor
|
||||
static int kwin_shape_event;
|
||||
};
|
||||
|
||||
class Motif
|
||||
|
@ -244,68 +191,34 @@ void grabXServer();
|
|||
void ungrabXServer();
|
||||
bool grabbedXServer();
|
||||
|
||||
inline
|
||||
Display* display()
|
||||
{
|
||||
return QX11Info::display();
|
||||
}
|
||||
|
||||
inline
|
||||
Window rootWindow()
|
||||
{
|
||||
return QX11Info::appRootWindow();
|
||||
}
|
||||
|
||||
inline
|
||||
Window xTime()
|
||||
{
|
||||
return QX11Info::appTime();
|
||||
}
|
||||
|
||||
inline
|
||||
int displayWidth()
|
||||
{
|
||||
return XDisplayWidth( display(), DefaultScreen( display()));
|
||||
}
|
||||
|
||||
inline
|
||||
int displayHeight()
|
||||
{
|
||||
return XDisplayHeight( display(), DefaultScreen( display()));
|
||||
}
|
||||
|
||||
class Scene;
|
||||
extern Scene* scene;
|
||||
inline bool compositing() { return scene != NULL; }
|
||||
|
||||
// the docs say it's UrgencyHint, but it's often #defined as XUrgencyHint
|
||||
#ifndef UrgencyHint
|
||||
#define UrgencyHint XUrgencyHint
|
||||
#endif
|
||||
|
||||
// for STL-like algo's
|
||||
#define KWIN_CHECK_PREDICATE( name, cls, check ) \
|
||||
#define KWIN_CHECK_PREDICATE( name, check ) \
|
||||
struct name \
|
||||
{ \
|
||||
inline bool operator()( const cls* cl ) { return check; }; \
|
||||
inline bool operator()( const Client* cl ) { return check; }; \
|
||||
}
|
||||
|
||||
#define KWIN_COMPARE_PREDICATE( name, cls, type, check ) \
|
||||
#define KWIN_COMPARE_PREDICATE( name, type, check ) \
|
||||
struct name \
|
||||
{ \
|
||||
typedef type type_helper; /* in order to work also with type being 'const Client*' etc. */ \
|
||||
inline name( const type_helper& compare_value ) : value( compare_value ) {}; \
|
||||
inline bool operator()( const cls* cl ) { return check; }; \
|
||||
inline bool operator()( const Client* cl ) { return check; }; \
|
||||
const type_helper& value; \
|
||||
}
|
||||
|
||||
#define KWIN_PROCEDURE( name, cls, action ) \
|
||||
#define KWIN_PROCEDURE( name, action ) \
|
||||
struct name \
|
||||
{ \
|
||||
inline void operator()( cls* cl ) { action; }; \
|
||||
inline void operator()( Client* cl ) { action; }; \
|
||||
}
|
||||
|
||||
KWIN_CHECK_PREDICATE( TruePredicate, Client, cl == cl /*true, avoid warning about 'cl' */ );
|
||||
KWIN_CHECK_PREDICATE( TruePredicate, cl == cl /*true, avoid warning about 'cl' */ );
|
||||
|
||||
template< typename T >
|
||||
Client* findClientInList( const ClientList& list, T predicate )
|
||||
|
@ -318,17 +231,6 @@ Client* findClientInList( const ClientList& list, T predicate )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
Unmanaged* findUnmanagedInList( const UnmanagedList& list, T predicate )
|
||||
{
|
||||
for ( UnmanagedList::ConstIterator it = list.begin(); it != list.end(); ++it)
|
||||
{
|
||||
if ( predicate( const_cast< const Unmanaged* >( *it)))
|
||||
return *it;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
int timestampCompare( Time time1, Time time2 ) // like strcmp()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue