second half of the "avoid stealing focus if possible" fix

svn path=/trunk/kdebase/kwin/; revision=139642
This commit is contained in:
Matthias Ettrich 2002-02-28 22:11:43 +00:00
parent 7d50916939
commit e34a6ee283
7 changed files with 182 additions and 109 deletions

View file

@ -45,6 +45,9 @@ Atoms::Atoms()
atoms[n] = &kde_wm_change_state; atoms[n] = &kde_wm_change_state;
names[n++] = (char *) "_KDE_WM_CHANGE_STATE"; names[n++] = (char *) "_KDE_WM_CHANGE_STATE";
atoms[n] = &kde_net_user_time;
names[n++] = (char *) "_KDE_NET_USER_TIME";
Atom fake; Atom fake;
atoms[n] = &fake; atoms[n] = &fake;
names[n++] = (char *) "_DT_SM_WINDOW_INFO"; names[n++] = (char *) "_DT_SM_WINDOW_INFO";

View file

@ -23,6 +23,7 @@ public:
Atom motif_wm_hints; Atom motif_wm_hints;
Atom net_wm_context_help; Atom net_wm_context_help;
Atom kde_wm_change_state; Atom kde_wm_change_state;
Atom kde_net_user_time;
}; };

View file

@ -103,10 +103,15 @@ public:
// to resolve them properly // to resolve them properly
extern Atom qt_wm_state; extern Atom qt_wm_state;
extern Time kwin_time; extern Time qt_x_time;
extern Atom qt_window_role; extern Atom qt_window_role;
extern Atom qt_sm_client_id; extern Atom qt_sm_client_id;
static int nullErrorHandler(Display *, XErrorEvent *)
{
return 0;
}
using namespace KWinInternal; using namespace KWinInternal;
static bool resizeHorizontalDirectionFixed = FALSE; static bool resizeHorizontalDirectionFixed = FALSE;
@ -157,7 +162,7 @@ static void sendClientMessage(Window w, Atom a, long x){
ev.xclient.message_type = a; ev.xclient.message_type = a;
ev.xclient.format = 32; ev.xclient.format = 32;
ev.xclient.data.l[0] = x; ev.xclient.data.l[0] = x;
ev.xclient.data.l[1] = kwin_time; ev.xclient.data.l[1] = qt_x_time;
mask = 0L; mask = 0L;
if (w == qt_xrootwin()) if (w == qt_xrootwin())
mask = SubstructureRedirectMask; /* magic! */ mask = SubstructureRedirectMask; /* magic! */
@ -399,24 +404,24 @@ void WindowWrapper::releaseWindow()
bool WindowWrapper::x11Event( XEvent * e) bool WindowWrapper::x11Event( XEvent * e)
{ {
switch ( e->type ) { switch ( e->type ) {
case ButtonPress: case ButtonPress: {
{ ((Client*)parentWidget())->updateUserTime();
uint keyModX = (options->keyCmdAllModKey() == Qt::Key_Meta) ? uint keyModX = (options->keyCmdAllModKey() == Qt::Key_Meta) ?
KKeyNative::modX(KKey::WIN) : KKeyNative::modX(KKey::WIN) :
KKeyNative::modX(KKey::ALT); KKeyNative::modX(KKey::ALT);
bool bModKeyHeld = e->xbutton.state & keyModX; bool bModKeyHeld = e->xbutton.state & keyModX;
if ( ((Client*)parentWidget())->isActive() if ( ((Client*)parentWidget())->isActive()
&& ( options->focusPolicy != Options::ClickToFocus && ( options->focusPolicy != Options::ClickToFocus
&& options->clickRaise && !bModKeyHeld ) ) { && options->clickRaise && !bModKeyHeld ) ) {
if ( e->xbutton.button < 4 ) // exclude wheel if ( e->xbutton.button < 4 ) // exclude wheel
((Client*)parentWidget())->autoRaise(); ((Client*)parentWidget())->autoRaise();
ungrabButton( winId(), None ); ungrabButton( winId(), None );
} }
Options::MouseCommand com = Options::MouseNothing; Options::MouseCommand com = Options::MouseNothing;
if ( bModKeyHeld ){ if ( bModKeyHeld ){
switch (e->xbutton.button) { switch (e->xbutton.button) {
case Button1: case Button1:
com = options->commandAll1(); com = options->commandAll1();
break; break;
@ -426,9 +431,9 @@ bool WindowWrapper::x11Event( XEvent * e)
case Button3: case Button3:
com = options->commandAll3(); com = options->commandAll3();
break; break;
} }
} else { } else {
switch (e->xbutton.button) { switch (e->xbutton.button) {
case Button1: case Button1:
com = options->commandWindow1(); com = options->commandWindow1();
break; break;
@ -440,22 +445,21 @@ bool WindowWrapper::x11Event( XEvent * e)
break; break;
default: default:
com = Options::MouseActivateAndPassClick; com = Options::MouseActivateAndPassClick;
} }
} }
bool replay = ( (Client*)parentWidget() )->performMouseCommand( com, bool replay = ( (Client*)parentWidget() )->performMouseCommand( com,
QPoint( e->xbutton.x_root, e->xbutton.y_root) ); QPoint( e->xbutton.x_root, e->xbutton.y_root) );
if ( ((Client*)parentWidget())->windowType() != NET::Normal && if ( ((Client*)parentWidget())->windowType() != NET::Normal &&
((Client*)parentWidget())->windowType() != NET::Dialog && ((Client*)parentWidget())->windowType() != NET::Dialog &&
((Client*)parentWidget())->windowType() != NET::Override ) ((Client*)parentWidget())->windowType() != NET::Override )
replay = TRUE; replay = TRUE;
XAllowEvents(qt_xdisplay(), replay? ReplayPointer : SyncPointer, CurrentTime ); //kwin_time); XAllowEvents(qt_xdisplay(), replay? ReplayPointer : SyncPointer, CurrentTime ); //qt_x_time);
return TRUE; return TRUE;
} } break;
break;
case ButtonRelease: case ButtonRelease:
XAllowEvents(qt_xdisplay(), SyncPointer, CurrentTime ); //kwin_time); XAllowEvents(qt_xdisplay(), SyncPointer, CurrentTime ); //qt_x_time);
break; break;
default: default:
break; break;
@ -490,7 +494,8 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
NET::WMWindowType | NET::WMWindowType |
NET::WMStrut | NET::WMStrut |
NET::WMName | NET::WMName |
NET::WMIconGeometry NET::WMIconGeometry |
NET::WMPid
; ;
info = new WinInfo( this, qt_xdisplay(), win, qt_xrootwin(), properties ); info = new WinInfo( this, qt_xdisplay(), win, qt_xrootwin(), properties );
@ -826,10 +831,23 @@ bool Client::manage( bool isMapped, bool doNotShow, bool isInitial )
if ( isMapped ) { if ( isMapped ) {
show(); show();
} else { } else {
workspace()->raiseClient( this ); // ensure constrains // we only raise (and potentially activate) new clients if
show(); // the user does not actively work in the currently active
if ( options->focusPolicyIsReasonable() && wantsTabFocus() ) // client. We can safely drop the activation when the
workspace()->requestFocus( this ); // NET_KDE_USER_TIME of the currently active client is
// defined and more recent than the one of the new client
// (which we set ourselves in CreateNotify in
// workspace.cpp)
Client* ac = workspace()->activeClient();
if ( ac && ac->userTime() <= userTime() ) {
workspace()->raiseClient( this );
show();
if ( options->focusPolicyIsReasonable() && wantsTabFocus() )
workspace()->requestFocus( this );
} else {
workspace()->stackClientUnderActive( this );
show();
}
} }
} }
@ -840,6 +858,46 @@ bool Client::manage( bool isMapped, bool doNotShow, bool isInitial )
} }
/*!
Updates the user time on the client window. This is called inside
kwin for every action with the window that qualifies for user
interaction (clicking on it, activate it externally, etc.).
*/
void Client::updateUserTime()
{
if ( window() ) {
timeval tv;
gettimeofday( &tv, NULL );
unsigned long now = tv.tv_sec * 10 + tv.tv_usec / 100000;
XChangeProperty(qt_xdisplay(), window(),
atoms->kde_net_user_time, XA_CARDINAL,
32, PropModeReplace, (unsigned char *)&now, 1);
}
}
unsigned long Client::userTime()
{
unsigned long result = 0;
Atom type;
int format, status;
unsigned long nitems = 0;
unsigned long extra = 0;
unsigned char *data = 0;
XErrorHandler oldHandler = XSetErrorHandler(nullErrorHandler);
status = XGetWindowProperty( qt_xdisplay(), window(),
atoms->kde_net_user_time,
0, 10000, FALSE, XA_CARDINAL, &type, &format,
&nitems, &extra, &data );
XSetErrorHandler(oldHandler);
if (status == Success ) {
if (data && nitems > 0)
result = *((long*) data);
XFree(data);
}
return result;
}
/*! /*!
Gets the client's normal WM hints and reconfigures itself respectively. Gets the client's normal WM hints and reconfigures itself respectively.
*/ */
@ -1611,7 +1669,7 @@ void Client::mouseMoveEvent( QMouseEvent * e)
break; break;
} }
} }
workspace()->clientMoved(globalPos, kwin_time); workspace()->clientMoved(globalPos, qt_x_time);
// QApplication::syncX(); // process our own configure events synchronously. // QApplication::syncX(); // process our own configure events synchronously.
} }
@ -2061,7 +2119,10 @@ void Client::gravitate( bool invert )
*/ */
bool Client::x11Event( XEvent * e) bool Client::x11Event( XEvent * e)
{ {
if ( e->type == EnterNotify && ( e->xcrossing.mode == NotifyNormal || e->xcrossing.mode == NotifyUngrab ) ) { if ( e->type == EnterNotify &&
( e->xcrossing.mode == NotifyNormal ||
( !options->focusPolicyIsReasonable() &&
e->xcrossing.mode == NotifyUngrab ) ) ) {
if (options->shadeHover && isShade() && !isDesktop()) { if (options->shadeHover && isShade() && !isDesktop()) {
delete shadeHoverTimer; delete shadeHoverTimer;
@ -2073,8 +2134,9 @@ bool Client::x11Event( XEvent * e)
if ( options->focusPolicy == Options::ClickToFocus ) if ( options->focusPolicy == Options::ClickToFocus )
return TRUE; return TRUE;
if ( options->autoRaise && !isDesktop() && !isDock() && !isMenu() && workspace()->focusChangeEnabled() if ( options->autoRaise && !isDesktop() &&
&& workspace()->topClientOnDesktop() != this ) { !isDock() && !isMenu() && workspace()->focusChangeEnabled() &&
workspace()->topClientOnDesktop() != this ) {
delete autoRaiseTimer; delete autoRaiseTimer;
autoRaiseTimer = new QTimer( this ); autoRaiseTimer = new QTimer( this );
connect( autoRaiseTimer, SIGNAL( timeout() ), this, SLOT( autoRaise() ) ); connect( autoRaiseTimer, SIGNAL( timeout() ), this, SLOT( autoRaise() ) );
@ -2420,7 +2482,7 @@ void Client::takeFocus( bool force )
// Qt may delay the mapping which may cause XSetInputFocus to fail, force show window // Qt may delay the mapping which may cause XSetInputFocus to fail, force show window
QApplication::sendPostedEvents( windowWrapper(), QEvent::ShowWindowRequest ); QApplication::sendPostedEvents( windowWrapper(), QEvent::ShowWindowRequest );
XSetInputFocus( qt_xdisplay(), win, RevertToPointerRoot, kwin_time ); XSetInputFocus( qt_xdisplay(), win, RevertToPointerRoot, qt_x_time );
} }
if ( Ptakefocus ) if ( Ptakefocus )
sendClientMessage(win, atoms->wm_protocols, atoms->wm_take_focus); sendClientMessage(win, atoms->wm_protocols, atoms->wm_take_focus);
@ -2650,11 +2712,6 @@ void Client::keyPressEvent( uint key_code )
QCursor::setPos( pos ); QCursor::setPos( pos );
} }
static int nullErrorHandler(Display *, XErrorEvent *)
{
return 0;
}
static QCString getStringProperty(WId w, Atom prop, char separator=0) static QCString getStringProperty(WId w, Atom prop, char separator=0)
{ {
Atom type; Atom type;

View file

@ -211,6 +211,8 @@ public:
void keyPressEvent( uint key_code ); void keyPressEvent( uint key_code );
void updateUserTime();
public slots: public slots:
void iconify(); void iconify();
void closeWindow(); void closeWindow();
@ -276,6 +278,8 @@ private:
void fetchName(); void fetchName();
void gravitate( bool invert ); void gravitate( bool invert );
unsigned long userTime();
void startMoveResize(); void startMoveResize();
void stopMoveResize(); void stopMoveResize();

View file

@ -43,8 +43,7 @@ Options* options;
Atoms* atoms; Atoms* atoms;
extern Time qt_x_time; // workaround for Qt < 2.3.2 extern Time qt_x_time;
Time kwin_time = CurrentTime;
int kwin_screen_number = -1; int kwin_screen_number = -1;
static bool initting = FALSE; static bool initting = FALSE;
@ -88,7 +87,7 @@ int x11ErrorHandler(Display *d, XErrorEvent *e){
} }
/*! /*!
Updates kwin_time by receiving a current timestamp from the server. Updates qt_x_time by receiving a current timestamp from the server.
Use this function only when really necessary. Keep in mind that it's Use this function only when really necessary. Keep in mind that it's
a roundtrip to the X-Server. a roundtrip to the X-Server.
@ -103,8 +102,7 @@ void kwin_updateTime()
PropModeAppend, (unsigned char*) &data, 1); PropModeAppend, (unsigned char*) &data, 1);
XEvent ev; XEvent ev;
XWindowEvent( qt_xdisplay(), w->winId(), PropertyChangeMask, &ev ); XWindowEvent( qt_xdisplay(), w->winId(), PropertyChangeMask, &ev );
kwin_time = ev.xproperty.time; qt_x_time = ev.xproperty.time;
qt_x_time = kwin_time;
} }
@ -143,36 +141,10 @@ Application::~Application()
} }
bool Application::x11EventFilter( XEvent *e ) bool Application::x11EventFilter( XEvent *e )
{ {
switch ( e->type ) { if ( Workspace::self()->workspaceEvent( e ) )
case ButtonPress:
case ButtonRelease:
kwin_time = e->xbutton.time;
qt_x_time = kwin_time; // workaround for Qt < 2.3.2
break;
case MotionNotify:
kwin_time = e->xmotion.time;
qt_x_time = kwin_time; // workaround for Qt < 2.3.2
break;
case KeyPress:
case KeyRelease:
kwin_time = e->xkey.time;
qt_x_time = kwin_time; // workaround for Qt < 2.3.2
break;
case PropertyNotify:
kwin_time = e->xproperty.time;
qt_x_time = kwin_time; // workaround for Qt < 2.3.2
break;
case EnterNotify:
case LeaveNotify:
kwin_time = e->xcrossing.time;
qt_x_time = kwin_time; // workaround for Qt < 2.3.2
default:
break;
}
if ( Workspace::self()->workspaceEvent( e ) )
return TRUE; return TRUE;
return KApplication::x11EventFilter( e ); return KApplication::x11EventFilter( e );
} }

View file

@ -46,6 +46,7 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
#include <X11/keysymdef.h> #include <X11/keysymdef.h>
#include <X11/extensions/shape.h> #include <X11/extensions/shape.h>
#include <X11/cursorfont.h> #include <X11/cursorfont.h>
#include <sys/time.h>
const int XIconicState = IconicState; const int XIconicState = IconicState;
#undef IconicState #undef IconicState
@ -142,7 +143,7 @@ QString Workspace::desktopName( int desk )
return QString::fromUtf8( rootInfo->desktopName( desk ) ); return QString::fromUtf8( rootInfo->desktopName( desk ) );
} }
extern Time kwin_time; extern Time qt_x_time;
extern void kwin_updateTime(); extern void kwin_updateTime();
// used to store the return values of // used to store the return values of
@ -511,7 +512,7 @@ bool Workspace::workspaceEvent( XEvent * e )
{ {
if ( mouse_emulation && e->type == ButtonPress || e->type == ButtonRelease ) { if ( mouse_emulation && e->type == ButtonPress || e->type == ButtonRelease ) {
mouse_emulation = FALSE; mouse_emulation = FALSE;
XUngrabKeyboard( qt_xdisplay(), kwin_time ); XUngrabKeyboard( qt_xdisplay(), qt_x_time );
} }
if ( e->type == PropertyNotify || e->type == ClientMessage ) { if ( e->type == PropertyNotify || e->type == ClientMessage ) {
@ -532,8 +533,8 @@ bool Workspace::workspaceEvent( XEvent * e )
switch (e->type) { switch (e->type) {
case ButtonPress: case ButtonPress:
if ( tab_grab || control_grab ) { if ( tab_grab || control_grab ) {
XUngrabKeyboard(qt_xdisplay(), kwin_time); XUngrabKeyboard(qt_xdisplay(), qt_x_time);
XUngrabPointer( qt_xdisplay(), kwin_time); XUngrabPointer( qt_xdisplay(), qt_x_time);
tab_box->hide(); tab_box->hide();
keys->setEnabled( true ); keys->setEnabled( true );
tab_grab = control_grab = false; tab_grab = control_grab = false;
@ -542,6 +543,18 @@ bool Workspace::workspaceEvent( XEvent * e )
case ButtonRelease: case ButtonRelease:
case MotionNotify: case MotionNotify:
break; break;
case CreateNotify:
if ( e->xcreatewindow.parent == root &&
!QWidget::find( e->xcreatewindow.window) ) {
timeval tv;
gettimeofday( &tv, NULL );
unsigned long now = tv.tv_sec * 10 + tv.tv_usec / 100000;
XChangeProperty(qt_xdisplay(), e->xcreatewindow.window,
atoms->kde_net_user_time, XA_CARDINAL,
32, PropModeReplace, (unsigned char *)&now, 1);
}
break;
case UnmapNotify: case UnmapNotify:
// this is special due to // this is special due to
// SubstructureNotifyMask. e->xany.window is the window the // SubstructureNotifyMask. e->xany.window is the window the
@ -854,7 +867,7 @@ void Workspace::slotWalkThroughWindows()
if ( tab_grab || control_grab ) if ( tab_grab || control_grab )
return; return;
if ( options->altTabStyle == Options::CDE || !options->focusPolicyIsReasonable() ) { if ( options->altTabStyle == Options::CDE || !options->focusPolicyIsReasonable() ) {
//XUngrabKeyboard(qt_xdisplay(), kwin_time); // need that because of accelerator raw mode //XUngrabKeyboard(qt_xdisplay(), qt_x_time); // need that because of accelerator raw mode
// CDE style raise / lower // CDE style raise / lower
CDEWalkThroughWindows( true ); CDEWalkThroughWindows( true );
} else { } else {
@ -956,14 +969,14 @@ bool Workspace::startKDEWalkThroughWindows()
ButtonMotionMask | EnterWindowMask | ButtonMotionMask | EnterWindowMask |
LeaveWindowMask | PointerMotionMask), LeaveWindowMask | PointerMotionMask),
GrabModeAsync, GrabModeAsync, GrabModeAsync, GrabModeAsync,
None, None, kwin_time ) != GrabSuccess ) { None, None, qt_x_time ) != GrabSuccess ) {
return FALSE; return FALSE;
} }
if ( XGrabKeyboard(qt_xdisplay(), if ( XGrabKeyboard(qt_xdisplay(),
root, FALSE, root, FALSE,
GrabModeAsync, GrabModeAsync, GrabModeAsync, GrabModeAsync,
kwin_time) != GrabSuccess ) { qt_x_time) != GrabSuccess ) {
XUngrabPointer( qt_xdisplay(), kwin_time); XUngrabPointer( qt_xdisplay(), qt_x_time);
return FALSE; return FALSE;
} }
tab_grab = TRUE; tab_grab = TRUE;
@ -980,14 +993,14 @@ bool Workspace::startWalkThroughDesktops( int mode )
ButtonMotionMask | EnterWindowMask | ButtonMotionMask | EnterWindowMask |
LeaveWindowMask | PointerMotionMask), LeaveWindowMask | PointerMotionMask),
GrabModeAsync, GrabModeAsync, GrabModeAsync, GrabModeAsync,
None, None, kwin_time ) != GrabSuccess ) { None, None, qt_x_time ) != GrabSuccess ) {
return FALSE; return FALSE;
} }
if ( XGrabKeyboard(qt_xdisplay(), if ( XGrabKeyboard(qt_xdisplay(),
root, FALSE, root, FALSE,
GrabModeAsync, GrabModeAsync, GrabModeAsync, GrabModeAsync,
kwin_time) != GrabSuccess ) { qt_x_time) != GrabSuccess ) {
XUngrabPointer( qt_xdisplay(), kwin_time); XUngrabPointer( qt_xdisplay(), qt_x_time);
return FALSE; return FALSE;
} }
control_grab = TRUE; control_grab = TRUE;
@ -1113,8 +1126,8 @@ bool Workspace::keyPress(XKeyEvent& ev)
if (control_grab || tab_grab){ if (control_grab || tab_grab){
if ((keyQt & 0xffff) == Qt::Key_Escape){ if ((keyQt & 0xffff) == Qt::Key_Escape){
XUngrabKeyboard(qt_xdisplay(), kwin_time); XUngrabKeyboard(qt_xdisplay(), qt_x_time);
XUngrabPointer( qt_xdisplay(), kwin_time); XUngrabPointer( qt_xdisplay(), qt_x_time);
tab_box->hide(); tab_box->hide();
keys->setEnabled( true ); keys->setEnabled( true );
tab_grab = FALSE; tab_grab = FALSE;
@ -1167,8 +1180,8 @@ bool Workspace::keyRelease(XKeyEvent& ev)
if( !release ) if( !release )
return FALSE; return FALSE;
if (tab_grab){ if (tab_grab){
XUngrabPointer( qt_xdisplay(), kwin_time); XUngrabPointer( qt_xdisplay(), qt_x_time);
XUngrabKeyboard(qt_xdisplay(), kwin_time); XUngrabKeyboard(qt_xdisplay(), qt_x_time);
tab_box->hide(); tab_box->hide();
keys->setEnabled( true ); keys->setEnabled( true );
tab_grab = false; tab_grab = false;
@ -1177,8 +1190,8 @@ bool Workspace::keyRelease(XKeyEvent& ev)
} }
} }
if (control_grab){ if (control_grab){
XUngrabPointer( qt_xdisplay(), kwin_time); XUngrabPointer( qt_xdisplay(), qt_x_time);
XUngrabKeyboard(qt_xdisplay(), kwin_time); XUngrabKeyboard(qt_xdisplay(), qt_x_time);
tab_box->hide(); tab_box->hide();
keys->setEnabled( true ); keys->setEnabled( true );
control_grab = False; control_grab = False;
@ -1394,6 +1407,7 @@ void Workspace::activateClient( Client* c, bool force )
if (!c->isOnDesktop(currentDesktop()) ) { if (!c->isOnDesktop(currentDesktop()) ) {
setCurrentDesktop( c->desktop() ); setCurrentDesktop( c->desktop() );
} }
c->updateUserTime();
} }
@ -2079,7 +2093,6 @@ void Workspace::lowerClient( Client* c )
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) { for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
new_stack[i++] = (*it)->winId(); new_stack[i++] = (*it)->winId();
} }
// XRaiseWindow(qt_xdisplay(), new_stack[0]);
XRestackWindows(qt_xdisplay(), new_stack, i); XRestackWindows(qt_xdisplay(), new_stack, i);
delete [] new_stack; delete [] new_stack;
@ -2166,7 +2179,6 @@ void Workspace::raiseClient( Client* c )
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) { for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
new_stack[i++] = (*it)->winId(); new_stack[i++] = (*it)->winId();
} }
// XRaiseWindow(qt_xdisplay(), new_stack[0]);
XRestackWindows(qt_xdisplay(), new_stack, i); XRestackWindows(qt_xdisplay(), new_stack, i);
delete [] new_stack; delete [] new_stack;
@ -2179,6 +2191,29 @@ void Workspace::raiseClient( Client* c )
raiseElectricBorders(); raiseElectricBorders();
} }
void Workspace::stackClientUnderActive( Client* c )
{
if ( !active_client || !c || active_client == c )
return;
ClientList::Iterator it = stacking_order.find( active_client );
if ( it == stacking_order.end() )
return;
stacking_order.remove( c );
stacking_order.insert( it, c );
stacking_order = constrainedStackingOrder( stacking_order );
Window* new_stack = new Window[ stacking_order.count() + 1 ];
int i = 0;
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
new_stack[i++] = (*it)->winId();
}
XRestackWindows(qt_xdisplay(), new_stack, i);
delete [] new_stack;
propagateClients( TRUE );
}
void Workspace::raiseOrLowerClient( Client *c) void Workspace::raiseOrLowerClient( Client *c)
{ {
if (!c) return; if (!c) return;
@ -2264,7 +2299,7 @@ void Workspace::focusToNull(){
InputOnly, CopyFromParent, mask, &attr); InputOnly, CopyFromParent, mask, &attr);
XMapWindow(qt_xdisplay(), null_focus_window); XMapWindow(qt_xdisplay(), null_focus_window);
} }
XSetInputFocus(qt_xdisplay(), null_focus_window, RevertToPointerRoot, kwin_time ); XSetInputFocus(qt_xdisplay(), null_focus_window, RevertToPointerRoot, qt_x_time );
if( !block_focus ) if( !block_focus )
setActiveClient( NULL ); setActiveClient( NULL );
} }
@ -2987,7 +3022,7 @@ void Workspace::slotMouseEmulation()
{ {
if ( mouse_emulation ) { if ( mouse_emulation ) {
XUngrabKeyboard(qt_xdisplay(), kwin_time); XUngrabKeyboard(qt_xdisplay(), qt_x_time);
mouse_emulation = FALSE; mouse_emulation = FALSE;
return; return;
} }
@ -2995,7 +3030,7 @@ void Workspace::slotMouseEmulation()
if ( XGrabKeyboard(qt_xdisplay(), if ( XGrabKeyboard(qt_xdisplay(),
root, FALSE, root, FALSE,
GrabModeAsync, GrabModeAsync, GrabModeAsync, GrabModeAsync,
kwin_time) == GrabSuccess ) { qt_x_time) == GrabSuccess ) {
mouse_emulation = TRUE; mouse_emulation = TRUE;
mouse_emulation_state = 0; mouse_emulation_state = 0;
mouse_emulation_window = 0; mouse_emulation_window = 0;
@ -3365,7 +3400,7 @@ unsigned int Workspace::sendFakedMouseEvent( QPoint pos, WId w, MouseEmulation t
e.window = w; e.window = w;
e.root = qt_xrootwin(); e.root = qt_xrootwin();
e.subwindow = w; e.subwindow = w;
e.time = kwin_time; e.time = qt_x_time;
e.x = x; e.x = x;
e.y = y; e.y = y;
e.x_root = pos.x(); e.x_root = pos.x();
@ -3379,7 +3414,7 @@ unsigned int Workspace::sendFakedMouseEvent( QPoint pos, WId w, MouseEmulation t
e.window = w; e.window = w;
e.root = qt_xrootwin(); e.root = qt_xrootwin();
e.subwindow = w; e.subwindow = w;
e.time = kwin_time; e.time = qt_x_time;
e.x = x; e.x = x;
e.y = y; e.y = y;
e.x_root = pos.x(); e.x_root = pos.x();
@ -3495,7 +3530,7 @@ bool Workspace::keyPressMouseEmulation( XKeyEvent& ev )
} }
// fall through // fall through
case XK_Escape: case XK_Escape:
XUngrabKeyboard(qt_xdisplay(), kwin_time); XUngrabKeyboard(qt_xdisplay(), qt_x_time);
mouse_emulation = FALSE; mouse_emulation = FALSE;
return TRUE; return TRUE;
default: default:
@ -3657,7 +3692,7 @@ void Workspace::storeLegacySession( KConfig* config )
ev.xclient.message_type = atoms->wm_protocols; ev.xclient.message_type = atoms->wm_protocols;
ev.xclient.format = 32; ev.xclient.format = 32;
ev.xclient.data.l[0] = atoms->wm_save_yourself; ev.xclient.data.l[0] = atoms->wm_save_yourself;
ev.xclient.data.l[1] = kwin_time; ev.xclient.data.l[1] = qt_x_time;
XSelectInput(newdisplay, w, PropertyChangeMask|StructureNotifyMask); XSelectInput(newdisplay, w, PropertyChangeMask|StructureNotifyMask);
XSendEvent(newdisplay, w, False, 0, &ev); XSendEvent(newdisplay, w, False, 0, &ev);
} }
@ -4126,7 +4161,7 @@ void Workspace::focusEnsurance()
if ( !last_active_client ) if ( !last_active_client )
last_active_client = topClientOnDesktop(); last_active_client = topClientOnDesktop();
if ( last_active_client && last_active_client->isVisible() ) { if ( last_active_client && last_active_client->isVisible() ) {
kwin_time = CurrentTime; qt_x_time = CurrentTime;
requestFocus( last_active_client ); requestFocus( last_active_client );
} }
} }

View file

@ -163,6 +163,7 @@ public:
QPoint adjustClientPosition( Client* c, QPoint pos ); QPoint adjustClientPosition( Client* c, QPoint pos );
void raiseClient( Client* c ); void raiseClient( Client* c );
void lowerClient( Client* c ); void lowerClient( Client* c );
void stackClientUnderActive( Client* );
void raiseOrLowerClient( Client * ); void raiseOrLowerClient( Client * );
void reconfigure(); void reconfigure();