Perform whole new window managing with X server grab, in order to prevent
"smart" apps from doing stupid things before they get MapNotify. This avoids the recent Java+OracleInstaller strange problem too. The patch may look huge, but it's only adding two KWin wrappers for X(Un)GrabServer() and uncommenting the calls in Client::manage(). svn path=/trunk/kdebase/kwin/; revision=271152
This commit is contained in:
parent
e7d3ffaceb
commit
0ba12a0837
17 changed files with 70 additions and 20 deletions
|
@ -65,10 +65,6 @@ Atoms::Atoms()
|
|||
Atom fake;
|
||||
atoms[n] = &fake;
|
||||
names[n++] = (char *) "_DT_SM_WINDOW_INFO";
|
||||
|
||||
Atom dummy;
|
||||
atoms[n] = &dummy;
|
||||
names[n++] = (char *) "_ICEWM_WINOPTHINT";
|
||||
|
||||
XInternAtoms( qt_xdisplay(), names, n, FALSE, atoms_return );
|
||||
for (int i = 0; i < n; i++ )
|
||||
|
|
|
@ -170,4 +170,12 @@ QRegion Bridge::unobscuredRegion( const QRegion& r ) const
|
|||
return reg;
|
||||
}
|
||||
|
||||
void Bridge::grabXServer( bool grab )
|
||||
{
|
||||
if( grab )
|
||||
KWinInternal::grabXServer();
|
||||
else
|
||||
KWinInternal::ungrabXServer();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
1
bridge.h
1
bridge.h
|
@ -62,6 +62,7 @@ class Bridge : public KDecorationBridge
|
|||
virtual QWidget* initialParentWidget() const;
|
||||
virtual Qt::WFlags initialWFlags() const;
|
||||
virtual void helperShowHide( bool show );
|
||||
virtual void grabXServer( bool grab );
|
||||
private:
|
||||
Client* c;
|
||||
};
|
||||
|
|
|
@ -590,8 +590,7 @@ void Client::animateMinimizeOrUnminimize( bool minimize )
|
|||
tf = (after.top() - before.top())/step;
|
||||
bf = (after.bottom() - before.bottom())/step;
|
||||
|
||||
|
||||
XGrabServer( qt_xdisplay() );
|
||||
grabXServer();
|
||||
|
||||
QRect area = before;
|
||||
QRect area2;
|
||||
|
@ -642,7 +641,7 @@ void Client::animateMinimizeOrUnminimize( bool minimize )
|
|||
p.drawPixmap( area2.x(), area2.y(), pm2 );
|
||||
|
||||
p.end();
|
||||
XUngrabServer( qt_xdisplay() );
|
||||
ungrabXServer();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,3 +37,4 @@ porting:
|
|||
- animateIconifyOrDeiconify() -> animateMinimize() - just drop it if it's empty
|
||||
- pay special attention to SLOT() names and cases where you need to use 'widget()' instead of 'this'
|
||||
- buttons should use setCursor() if they don't want cursor set by mousePosition()
|
||||
- X(un)GrabServer() -> (un)grabXServer()
|
||||
|
|
|
@ -195,7 +195,7 @@ bool Decoration::animateMinimize(bool iconify)
|
|||
QPoint p3(int(cx + dw + dx), int(midy + dch));
|
||||
QPoint p4(int(cx - dx), p3.y());
|
||||
|
||||
XGrabServer(qt_xdisplay());
|
||||
grabXServer();
|
||||
|
||||
p.drawLine(p1, p2);
|
||||
p.drawLine(p2, p3);
|
||||
|
@ -211,7 +211,7 @@ bool Decoration::animateMinimize(bool iconify)
|
|||
p.drawLine(p3, p4);
|
||||
p.drawLine(p4, p1);
|
||||
|
||||
XUngrabServer(qt_xdisplay());
|
||||
ungrabXServer();
|
||||
|
||||
// FRAME qApp->processEvents(); // FRAME ???
|
||||
|
||||
|
@ -254,14 +254,14 @@ bool Decoration::animateMinimize(bool iconify)
|
|||
r.setWidth(r.width() - 2 * dx);
|
||||
r.setHeight(r.height() - 2 * dy);
|
||||
|
||||
XGrabServer(qt_xdisplay());
|
||||
grabXServer();
|
||||
|
||||
p.drawRect(r);
|
||||
p.flush();
|
||||
usleep(200);
|
||||
p.drawRect(r);
|
||||
|
||||
XUngrabServer(qt_xdisplay());
|
||||
ungrabXServer();
|
||||
|
||||
// FRAME qApp->processEvents();
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ bool Decoration::animateMinimize(bool iconify)
|
|||
);
|
||||
#endif
|
||||
|
||||
XGrabServer(qt_xdisplay());
|
||||
grabXServer();
|
||||
|
||||
p.drawLine(wingeom.bottomRight(), icongeom.bottomRight());
|
||||
p.drawLine(wingeom.bottomLeft(), icongeom.bottomLeft());
|
||||
|
@ -307,7 +307,7 @@ bool Decoration::animateMinimize(bool iconify)
|
|||
p.drawLine(wingeom.topLeft(), icongeom.topLeft());
|
||||
p.drawLine(wingeom.topRight(), icongeom.topRight());
|
||||
|
||||
XUngrabServer(qt_xdisplay());
|
||||
ungrabXServer();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1513,7 +1513,7 @@ bool Client::startMoveResize()
|
|||
if ( ( isMove() && options->moveMode != Options::Opaque )
|
||||
|| ( isResize() && options->resizeMode != Options::Opaque ) )
|
||||
{
|
||||
XGrabServer( qt_xdisplay() );
|
||||
grabXServer();
|
||||
kapp->sendPostedEvents();
|
||||
// we have server grab -> nothing should cause paint events
|
||||
// unfortunately, that's not completely true, Qt may generate
|
||||
|
@ -1549,7 +1549,7 @@ void Client::leaveMoveResize()
|
|||
}
|
||||
if ( ( isMove() && options->moveMode != Options::Opaque )
|
||||
|| ( isResize() && options->resizeMode != Options::Opaque ) )
|
||||
XUngrabServer( qt_xdisplay() );
|
||||
ungrabXServer();
|
||||
XUngrabKeyboard( qt_xdisplay(), qt_x_time );
|
||||
XUngrabPointer( qt_xdisplay(), qt_x_time );
|
||||
workspace()->setClientIsMoving(0);
|
||||
|
|
|
@ -383,6 +383,10 @@ void KDecorationPreviewBridge::helperShowHide( bool )
|
|||
{
|
||||
}
|
||||
|
||||
void KDecorationPreviewBridge::grabXServer( bool )
|
||||
{
|
||||
}
|
||||
|
||||
KDecorationPreviewOptions::KDecorationPreviewOptions()
|
||||
{
|
||||
d = new KDecorationOptionsPrivate;
|
||||
|
|
|
@ -105,6 +105,7 @@ class KDecorationPreviewBridge
|
|||
virtual QWidget* initialParentWidget() const;
|
||||
virtual Qt::WFlags initialWFlags() const;
|
||||
virtual void helperShowHide( bool show );
|
||||
virtual void grabXServer( bool grab );
|
||||
private:
|
||||
KDecorationPreview* preview;
|
||||
bool active;
|
||||
|
|
|
@ -52,7 +52,7 @@ void KillWindow::start()
|
|||
int escape_pressed = 0;
|
||||
int button_released = 0;
|
||||
|
||||
XGrabServer(qt_xdisplay());
|
||||
grabXServer();
|
||||
|
||||
while (!return_pressed && !escape_pressed && !button_released)
|
||||
{
|
||||
|
@ -101,7 +101,7 @@ void KillWindow::start()
|
|||
workspace->killWindowId( child );
|
||||
}
|
||||
|
||||
XUngrabServer(qt_xdisplay());
|
||||
ungrabXServer();
|
||||
|
||||
XUngrabKeyboard(qt_xdisplay(), CurrentTime);
|
||||
XUngrabPointer(qt_xdisplay(), CurrentTime);
|
||||
|
|
|
@ -289,6 +289,16 @@ void KDecoration::helperShowHide( bool show )
|
|||
void KDecoration::reset( unsigned long )
|
||||
{
|
||||
}
|
||||
|
||||
void KDecoration::grabXServer()
|
||||
{
|
||||
bridge_->grabXServer( true );
|
||||
}
|
||||
|
||||
void KDecoration::ungrabXServer()
|
||||
{
|
||||
bridge_->grabXServer( false );
|
||||
}
|
||||
|
||||
KDecoration::MousePosition KDecoration::mousePosition( const QPoint& p ) const
|
||||
{
|
||||
|
|
|
@ -547,7 +547,8 @@ class KDecoration
|
|||
virtual bool drawbound( const QRect& geom, bool clear );
|
||||
/**
|
||||
* This function may be reimplemented to provide custom minimize/restore animations
|
||||
* The reimplementation is allowed to perform X server grabs if necessary, but no
|
||||
* The reimplementation is allowed to perform X server grabs if necessary
|
||||
* (only using the functions provided by this API, no direct Xlib calls), but no
|
||||
* futher event processing is allowed (i.e. no kapp->processEvents()).
|
||||
* @a False should be returned if the default implementation should be used.
|
||||
* Note that you should not use this function to force disabling of the animation.
|
||||
|
@ -612,6 +613,14 @@ class KDecoration
|
|||
* Returns the factory that created this decoration.
|
||||
*/
|
||||
KDecorationFactory* factory() const;
|
||||
/**
|
||||
* Performs X server grab. It is safe to call it several times in a row.
|
||||
*/
|
||||
void grabXServer();
|
||||
/**
|
||||
* Ungrabs X server (if the number of ungrab attempts matches the number of grab attempts).
|
||||
*/
|
||||
void ungrabXServer();
|
||||
public slots:
|
||||
// requests from decoration
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ class KDecorationBridge : public KDecorationDefines
|
|||
virtual QWidget* initialParentWidget() const = 0;
|
||||
virtual Qt::WFlags initialWFlags() const = 0;
|
||||
virtual void helperShowHide( bool ) = 0;
|
||||
virtual void grabXServer( bool grab ) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -39,7 +39,7 @@ bool Client::manage( Window w, bool isMapped )
|
|||
if( !XGetWindowAttributes(qt_xdisplay(), w, &attr))
|
||||
return false;
|
||||
|
||||
// XGrabServer( qt_xdisplay()); // FRAME
|
||||
grabXServer();
|
||||
|
||||
// from this place on, manage() mustn't return false
|
||||
block_geometry = 1;
|
||||
|
@ -488,7 +488,7 @@ bool Client::manage( Window w, bool isMapped )
|
|||
|
||||
delete session;
|
||||
|
||||
// XUngrabServer( qt_xdisplay()); //FRAME
|
||||
ungrabXServer();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
14
utils.cpp
14
utils.cpp
|
@ -19,6 +19,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include "atoms.h"
|
||||
|
||||
#include <kxerrorhandler.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
|
@ -231,7 +232,20 @@ void updateXTime()
|
|||
qt_x_time = ev.xproperty.time;
|
||||
}
|
||||
|
||||
static int server_grab_count = 0;
|
||||
|
||||
void grabXServer()
|
||||
{
|
||||
if( ++server_grab_count == 1 )
|
||||
XGrabServer( qt_xdisplay());
|
||||
}
|
||||
|
||||
void ungrabXServer()
|
||||
{
|
||||
assert( server_grab_count > 0 );
|
||||
if( --server_grab_count == 0 )
|
||||
XUngrabServer( qt_xdisplay());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
|
2
utils.h
2
utils.h
|
@ -143,6 +143,8 @@ class KWinSelectionOwner
|
|||
|
||||
QCString getStringProperty(WId w, Atom prop, char separator=0);
|
||||
void updateXTime();
|
||||
void grabXServer();
|
||||
void ungrabXServer();
|
||||
|
||||
// the docs say it's UrgencyHint, but it's often #defined as XUrgencyHint
|
||||
#ifndef UrgencyHint
|
||||
|
|
|
@ -298,6 +298,7 @@ void Workspace::init()
|
|||
topmenu_height = 0;
|
||||
managing_topmenus = false;
|
||||
topmenu_space = NULL;
|
||||
// TODO grabXServer(); - where exactly put this? topmenu selection claiming down belong must be before
|
||||
|
||||
{ // begin updates blocker block
|
||||
StackingUpdatesBlocker blocker( this );
|
||||
|
@ -366,11 +367,13 @@ void Workspace::init()
|
|||
// and maybe in rare cases also if the selected client doesn't
|
||||
// want focus
|
||||
workspaceInit = false;
|
||||
// TODO ungrabXServer()
|
||||
}
|
||||
|
||||
Workspace::~Workspace()
|
||||
{
|
||||
blockStackingUpdates( true );
|
||||
// TODO grabXServer();
|
||||
// use stacking_order, so that kwin --replace keeps stacking order
|
||||
for( ClientList::ConstIterator it = stacking_order.begin();
|
||||
it != stacking_order.end();
|
||||
|
@ -400,6 +403,7 @@ Workspace::~Workspace()
|
|||
delete topmenu_watcher;
|
||||
delete topmenu_selection;
|
||||
delete topmenu_space;
|
||||
// TODO ungrabXServer();
|
||||
_self = 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue