00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <config-X11.h>
00029
00030 #include "client.h"
00031 #include "workspace.h"
00032 #include "atoms.h"
00033 #include "tabbox.h"
00034 #include "group.h"
00035 #include "rules.h"
00036 #include "unmanaged.h"
00037 #include "scene.h"
00038 #include "effects.h"
00039
00040 #include <QWhatsThis>
00041 #include <QApplication>
00042
00043 #include <kkeyserver.h>
00044
00045 #include <X11/extensions/shape.h>
00046 #include <X11/Xatom.h>
00047 #include <QX11Info>
00048
00049 #ifdef HAVE_XRANDR
00050 #include <X11/extensions/Xrandr.h>
00051 #endif
00052
00053 namespace KWin
00054 {
00055
00056
00057
00058
00059
00060 WinInfo::WinInfo( Client * c, Display * display, Window window,
00061 Window rwin, const unsigned long pr[], int pr_size )
00062 : NETWinInfo2( display, window, rwin, pr, pr_size, NET::WindowManager ), m_client( c )
00063 {
00064 }
00065
00066 void WinInfo::changeDesktop(int desktop)
00067 {
00068 m_client->workspace()->sendClientToDesktop( m_client, desktop, true );
00069 }
00070
00071 void WinInfo::changeFullscreenMonitors( NETFullscreenMonitors topology )
00072 {
00073 m_client->updateFullscreenMonitors( topology );
00074 }
00075
00076 void WinInfo::changeState( unsigned long state, unsigned long mask )
00077 {
00078 mask &= ~NET::Sticky;
00079 mask &= ~NET::Hidden;
00080 state &= mask;
00081
00082 if(( mask & NET::FullScreen ) != 0 && ( state & NET::FullScreen ) == 0 )
00083 m_client->setFullScreen( false, false );
00084 if ( (mask & NET::Max) == NET::Max )
00085 m_client->setMaximize( state & NET::MaxVert, state & NET::MaxHoriz );
00086 else if ( mask & NET::MaxVert )
00087 m_client->setMaximize( state & NET::MaxVert, m_client->maximizeMode() & Client::MaximizeHorizontal );
00088 else if ( mask & NET::MaxHoriz )
00089 m_client->setMaximize( m_client->maximizeMode() & Client::MaximizeVertical, state & NET::MaxHoriz );
00090
00091 if ( mask & NET::Shaded )
00092 m_client->setShade( state & NET::Shaded ? ShadeNormal : ShadeNone );
00093 if ( mask & NET::KeepAbove)
00094 m_client->setKeepAbove( (state & NET::KeepAbove) != 0 );
00095 if ( mask & NET::KeepBelow)
00096 m_client->setKeepBelow( (state & NET::KeepBelow) != 0 );
00097 if( mask & NET::SkipTaskbar )
00098 m_client->setSkipTaskbar( ( state & NET::SkipTaskbar ) != 0, true );
00099 if( mask & NET::SkipPager )
00100 m_client->setSkipPager( ( state & NET::SkipPager ) != 0 );
00101 if( mask & NET::DemandsAttention )
00102 m_client->demandAttention(( state & NET::DemandsAttention ) != 0 );
00103 if( mask & NET::Modal )
00104 m_client->setModal( ( state & NET::Modal ) != 0 );
00105
00106 if(( mask & NET::FullScreen ) != 0 && ( state & NET::FullScreen ) != 0 )
00107 m_client->setFullScreen( true, false );
00108 }
00109
00110 void WinInfo::disable()
00111 {
00112 m_client = NULL;
00113 }
00114
00115
00116
00117
00118
00119 RootInfo::RootInfo( Workspace* ws, Display *dpy, Window w, const char *name, unsigned long pr[], int pr_num, int scr )
00120 : NETRootInfo( dpy, w, name, pr, pr_num, scr )
00121 {
00122 workspace = ws;
00123 }
00124
00125 void RootInfo::changeNumberOfDesktops(int n)
00126 {
00127 workspace->setNumberOfDesktops( n );
00128 }
00129
00130 void RootInfo::changeCurrentDesktop(int d)
00131 {
00132 workspace->setCurrentDesktop( d );
00133 }
00134
00135 void RootInfo::changeActiveWindow( Window w, NET::RequestSource src, Time timestamp, Window active_window )
00136 {
00137 if( Client* c = workspace->findClient( WindowMatchPredicate( w )))
00138 {
00139 if( timestamp == CurrentTime )
00140 timestamp = c->userTime();
00141 if( src != NET::FromApplication && src != FromTool )
00142 src = NET::FromTool;
00143 if( src == NET::FromTool )
00144 workspace->activateClient( c, true );
00145 else
00146 {
00147 Client* c2;
00148 if( workspace->allowClientActivation( c, timestamp, false, true ))
00149 workspace->activateClient( c );
00150
00151 else if( active_window != None
00152 && ( c2 = workspace->findClient( WindowMatchPredicate( active_window ))) != NULL
00153 && workspace->allowClientActivation( c2,
00154 timestampCompare( timestamp, c2->userTime() > 0 ? timestamp : c2->userTime()), false, true ))
00155 {
00156 workspace->activateClient( c );
00157 }
00158 else
00159 c->demandAttention();
00160 }
00161 }
00162 }
00163
00164 void RootInfo::restackWindow( Window w, RequestSource src, Window above, int detail, Time timestamp )
00165 {
00166 if( Client* c = workspace->findClient( WindowMatchPredicate( w )))
00167 {
00168 if( timestamp == CurrentTime )
00169 timestamp = c->userTime();
00170 if( src != NET::FromApplication && src != FromTool )
00171 src = NET::FromTool;
00172 c->restackWindow( above, detail, src, timestamp, true );
00173 }
00174 }
00175
00176 void RootInfo::gotTakeActivity( Window w, Time timestamp, long flags )
00177 {
00178 if( Client* c = workspace->findClient( WindowMatchPredicate( w )))
00179 workspace->handleTakeActivity( c, timestamp, flags );
00180 }
00181
00182 void RootInfo::closeWindow(Window w)
00183 {
00184 Client* c = workspace->findClient( WindowMatchPredicate( w ));
00185 if ( c )
00186 c->closeWindow();
00187 }
00188
00189 void RootInfo::moveResize(Window w, int x_root, int y_root, unsigned long direction)
00190 {
00191 Client* c = workspace->findClient( WindowMatchPredicate( w ));
00192 if ( c )
00193 {
00194 updateXTime();
00195 c->NETMoveResize( x_root, y_root, (Direction)direction);
00196 }
00197 }
00198
00199 void RootInfo::moveResizeWindow(Window w, int flags, int x, int y, int width, int height )
00200 {
00201 Client* c = workspace->findClient( WindowMatchPredicate( w ));
00202 if ( c )
00203 c->NETMoveResizeWindow( flags, x, y, width, height );
00204 }
00205
00206 void RootInfo::gotPing( Window w, Time timestamp )
00207 {
00208 if( Client* c = workspace->findClient( WindowMatchPredicate( w )))
00209 c->gotPing( timestamp );
00210 }
00211
00212 void RootInfo::changeShowingDesktop( bool showing )
00213 {
00214 workspace->setShowingDesktop( showing );
00215 }
00216
00217
00218
00219
00220
00224 bool Workspace::workspaceEvent( XEvent * e )
00225 {
00226 if ( mouse_emulation && (e->type == ButtonPress || e->type == ButtonRelease ) )
00227 {
00228 mouse_emulation = false;
00229 ungrabXKeyboard();
00230 }
00231 if( effects && static_cast< EffectsHandlerImpl* >( effects )->hasKeyboardGrab()
00232 && ( e->type == KeyPress || e->type == KeyRelease ))
00233 return false;
00234
00235 if( e->type == PropertyNotify || e->type == ClientMessage )
00236 {
00237 unsigned long dirty[ NETRootInfo::PROPERTIES_SIZE ];
00238 rootInfo->event( e, dirty, NETRootInfo::PROPERTIES_SIZE );
00239 if( dirty[ NETRootInfo::PROTOCOLS ] & NET::DesktopNames )
00240 saveDesktopSettings();
00241 if( dirty[ NETRootInfo::PROTOCOLS2 ] & NET::WM2DesktopLayout )
00242 updateDesktopLayout();
00243 }
00244
00245
00246 switch (e->type)
00247 {
00248 case ButtonPress:
00249 case ButtonRelease:
00250 was_user_interaction = true;
00251
00252 case MotionNotify:
00253 if ( tab_grab || control_grab )
00254 {
00255 tab_box->handleMouseEvent( e );
00256 return true;
00257 }
00258 if( effects && static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowEvent( e ))
00259 return true;
00260 break;
00261 case KeyPress:
00262 {
00263 was_user_interaction = true;
00264 int keyQt;
00265 KKeyServer::xEventToQt(e, &keyQt);
00266
00267 if (movingClient)
00268 {
00269 movingClient->keyPressEvent(keyQt);
00270 return true;
00271 }
00272 if( tab_grab || control_grab )
00273 {
00274 tabBoxKeyPress( keyQt );
00275 return true;
00276 }
00277 break;
00278 }
00279 case KeyRelease:
00280 was_user_interaction = true;
00281 if( tab_grab || control_grab )
00282 {
00283 tabBoxKeyRelease( e->xkey );
00284 return true;
00285 }
00286 break;
00287 case ConfigureNotify:
00288 if( e->xconfigure.event == rootWindow())
00289 x_stacking_dirty = true;
00290 break;
00291 };
00292
00293 if( Client* c = findClient( WindowMatchPredicate( e->xany.window )))
00294 {
00295 if( c->windowEvent( e ))
00296 return true;
00297 }
00298 else if( Client* c = findClient( WrapperIdMatchPredicate( e->xany.window )))
00299 {
00300 if( c->windowEvent( e ))
00301 return true;
00302 }
00303 else if( Client* c = findClient( FrameIdMatchPredicate( e->xany.window )))
00304 {
00305 if( c->windowEvent( e ))
00306 return true;
00307 }
00308 else if( Unmanaged* c = findUnmanaged( WindowMatchPredicate( e->xany.window )))
00309 {
00310 if( c->windowEvent( e ))
00311 return true;
00312 }
00313 else
00314 {
00315 Window special = findSpecialEventWindow( e );
00316 if( special != None )
00317 if( Client* c = findClient( WindowMatchPredicate( special )))
00318 {
00319 if( c->windowEvent( e ))
00320 return true;
00321 }
00322 }
00323 if( movingClient != NULL && movingClient->moveResizeGrabWindow() == e->xany.window
00324 && ( e->type == MotionNotify || e->type == ButtonPress || e->type == ButtonRelease ))
00325 {
00326 if( movingClient->windowEvent( e ))
00327 return true;
00328 }
00329
00330 switch (e->type)
00331 {
00332 case CreateNotify:
00333 if ( e->xcreatewindow.parent == rootWindow() &&
00334 !QWidget::find( e->xcreatewindow.window) &&
00335 !e->xcreatewindow.override_redirect )
00336 {
00337
00338 Time t = xTime();
00339 XChangeProperty(display(), e->xcreatewindow.window,
00340 atoms->kde_net_wm_user_creation_time, XA_CARDINAL,
00341 32, PropModeReplace, (unsigned char *)&t, 1);
00342 }
00343 break;
00344
00345 case UnmapNotify:
00346 {
00347 return ( e->xunmap.event != e->xunmap.window );
00348 }
00349 case ReparentNotify:
00350 {
00351
00352
00353 return true;
00354 }
00355 case DestroyNotify:
00356 {
00357 return false;
00358 }
00359 case MapRequest:
00360 {
00361 updateXTime();
00362
00363
00364
00365 Client* c = findClient( WindowMatchPredicate( e->xmaprequest.window ));
00366 if ( !c )
00367 {
00368
00369
00370
00371
00372
00373
00374
00375
00376 c = createClient( e->xmaprequest.window, false );
00377 if( c == NULL )
00378 XMapRaised( display(), e->xmaprequest.window );
00379 return true;
00380 }
00381 if( c )
00382 {
00383 c->windowEvent( e );
00384 updateFocusChains( c, FocusChainUpdate );
00385 return true;
00386 }
00387 break;
00388 }
00389 case MapNotify:
00390 {
00391 if( e->xmap.override_redirect )
00392 {
00393 Unmanaged* c = findUnmanaged( WindowMatchPredicate( e->xmap.window ));
00394 if( c == NULL )
00395 c = createUnmanaged( e->xmap.window );
00396 if( c )
00397 return c->windowEvent( e );
00398 }
00399 return ( e->xmap.event != e->xmap.window );
00400 }
00401
00402 case EnterNotify:
00403 {
00404 if ( QWhatsThis::inWhatsThisMode() )
00405 {
00406 QWidget* w = QWidget::find( e->xcrossing.window );
00407 if ( w )
00408 QWhatsThis::leaveWhatsThisMode();
00409 }
00410 if( electricBorderEvent(e))
00411 return true;
00412 break;
00413 }
00414 case LeaveNotify:
00415 {
00416 if ( !QWhatsThis::inWhatsThisMode() )
00417 break;
00418
00419 Client* c = findClient( FrameIdMatchPredicate( e->xcrossing.window ));
00420 if ( c && e->xcrossing.detail != NotifyInferior )
00421 QWhatsThis::leaveWhatsThisMode();
00422 break;
00423 }
00424 case ConfigureRequest:
00425 {
00426 if ( e->xconfigurerequest.parent == rootWindow())
00427 {
00428 XWindowChanges wc;
00429 wc.border_width = e->xconfigurerequest.border_width;
00430 wc.x = e->xconfigurerequest.x;
00431 wc.y = e->xconfigurerequest.y;
00432 wc.width = e->xconfigurerequest.width;
00433 wc.height = e->xconfigurerequest.height;
00434 wc.sibling = None;
00435 wc.stack_mode = Above;
00436 unsigned int value_mask = e->xconfigurerequest.value_mask
00437 & ( CWX | CWY | CWWidth | CWHeight | CWBorderWidth );
00438 XConfigureWindow( display(), e->xconfigurerequest.window, value_mask, &wc );
00439 return true;
00440 }
00441 break;
00442 }
00443 case KeyPress:
00444 if ( mouse_emulation )
00445 return keyPressMouseEmulation( e->xkey );
00446 break;
00447 case KeyRelease:
00448 if ( mouse_emulation )
00449 return false;
00450 break;
00451 case FocusIn:
00452 if( e->xfocus.window == rootWindow()
00453 && ( e->xfocus.detail == NotifyDetailNone || e->xfocus.detail == NotifyPointerRoot ))
00454 {
00455 updateXTime();
00456 Window focus;
00457 int revert;
00458 XGetInputFocus( display(), &focus, &revert );
00459 if( focus == None || focus == PointerRoot )
00460 {
00461
00462 Client *c = mostRecentlyActivatedClient();
00463 if( c != NULL )
00464 requestFocus( c, true );
00465 else if( activateNextClient( NULL ))
00466 ;
00467 else
00468 focusToNull();
00469 }
00470 }
00471
00472 case FocusOut:
00473 return true;
00474 case ClientMessage:
00475 if( electricBorderEvent( e ))
00476 return true;
00477 break;
00478 case Expose:
00479 if( compositing()
00480 && ( e->xexpose.window == rootWindow()
00481 || overlay != None && e->xexpose.window == overlay ))
00482 {
00483 addRepaint( e->xexpose.x, e->xexpose.y, e->xexpose.width, e->xexpose.height );
00484 }
00485 break;
00486 case VisibilityNotify:
00487 if( compositing() && overlay != None && e->xvisibility.window == overlay )
00488 {
00489 bool was_visible = overlay_visible;
00490 overlay_visible = ( e->xvisibility.state != VisibilityFullyObscured );
00491 if( !was_visible && overlay_visible )
00492 {
00493 addRepaintFull();
00494 QTimer::singleShot( 2000, this, SLOT( addRepaintFull()));
00495 }
00496 checkCompositeTimer();
00497 }
00498 break;
00499 default:
00500 if( e->type == Extensions::randrNotifyEvent() && Extensions::randrAvailable() )
00501 {
00502 #ifdef HAVE_XRANDR
00503 XRRUpdateConfiguration( e );
00504 #endif
00505 if( compositing() )
00506 {
00507
00508
00509
00510 finishCompositing();
00511 QTimer::singleShot( 0, this, SLOT( setupCompositing() ) );
00512 }
00513 }
00514 else if( e->type == Extensions::syncAlarmNotifyEvent() && Extensions::syncAvailable())
00515 {
00516 #ifdef HAVE_XSYNC
00517 foreach( Client* c, clients )
00518 c->syncEvent( reinterpret_cast< XSyncAlarmNotifyEvent* >( e ));
00519 foreach( Client* c, desktops )
00520 c->syncEvent( reinterpret_cast< XSyncAlarmNotifyEvent* >( e ));
00521 #endif
00522 }
00523 break;
00524 }
00525 return false;
00526 }
00527
00528
00529
00530
00531 bool Workspace::workspaceEvent( QEvent* e )
00532 {
00533 if(( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease || e->type() == QEvent::ShortcutOverride )
00534 && effects && static_cast< EffectsHandlerImpl* >( effects )->hasKeyboardGrab())
00535 {
00536 static_cast< EffectsHandlerImpl* >( effects )->grabbedKeyboardEvent( static_cast< QKeyEvent* >( e ));
00537 return true;
00538 }
00539 return false;
00540 }
00541
00542
00543
00544
00545 Window Workspace::findSpecialEventWindow( XEvent* e )
00546 {
00547 switch( e->type )
00548 {
00549 case CreateNotify:
00550 return e->xcreatewindow.window;
00551 case DestroyNotify:
00552 return e->xdestroywindow.window;
00553 case UnmapNotify:
00554 return e->xunmap.window;
00555 case MapNotify:
00556 return e->xmap.window;
00557 case MapRequest:
00558 return e->xmaprequest.window;
00559 case ReparentNotify:
00560 return e->xreparent.window;
00561 case ConfigureNotify:
00562 return e->xconfigure.window;
00563 case GravityNotify:
00564 return e->xgravity.window;
00565 case ConfigureRequest:
00566 return e->xconfigurerequest.window;
00567 case CirculateNotify:
00568 return e->xcirculate.window;
00569 case CirculateRequest:
00570 return e->xcirculaterequest.window;
00571 default:
00572 return None;
00573 };
00574 }
00575
00576
00577
00578
00579
00583 bool Client::windowEvent( XEvent* e )
00584 {
00585 if( e->xany.window == window())
00586 {
00587 unsigned long dirty[ 2 ];
00588 double old_opacity = opacity();
00589 info->event( e, dirty, 2 );
00590
00591 if ( ( dirty[ WinInfo::PROTOCOLS ] & NET::WMName ) != 0 )
00592 fetchName();
00593 if ( ( dirty[ WinInfo::PROTOCOLS ] & NET::WMIconName ) != 0 )
00594 fetchIconicName();
00595 if ( ( dirty[ WinInfo::PROTOCOLS ] & NET::WMStrut ) != 0
00596 || ( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2ExtendedStrut ) != 0 )
00597 {
00598 if( isTopMenu())
00599 checkWorkspacePosition();
00600 workspace()->updateClientArea();
00601 }
00602 if ( ( dirty[ WinInfo::PROTOCOLS ] & NET::WMIcon) != 0 )
00603 getIcons();
00604
00605
00606
00607 if(( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2UserTime ) != 0 )
00608 {
00609 workspace()->setWasUserInteraction();
00610 updateUserTime( info->userTime());
00611 }
00612 if(( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2StartupId ) != 0 )
00613 startupIdChanged();
00614 if( dirty[ WinInfo::PROTOCOLS ] & NET::WMIconGeometry )
00615 {
00616 if( demandAttentionKNotifyTimer != NULL )
00617 demandAttentionKNotify();
00618 }
00619 if( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2Opacity )
00620 {
00621 if( compositing())
00622 {
00623 addRepaintFull();
00624 scene->windowOpacityChanged( this );
00625 if( effects )
00626 static_cast<EffectsHandlerImpl*>(effects)->windowOpacityChanged( effectWindow(), old_opacity );
00627 }
00628 else
00629 {
00630 NETWinInfo2 i( display(), frameId(), rootWindow(), 0 );
00631 i.setOpacity( info->opacity());
00632 }
00633 }
00634 }
00635
00636 switch (e->type)
00637 {
00638 case UnmapNotify:
00639 unmapNotifyEvent( &e->xunmap );
00640 break;
00641 case DestroyNotify:
00642 destroyNotifyEvent( &e->xdestroywindow );
00643 break;
00644 case MapRequest:
00645
00646 return mapRequestEvent( &e->xmaprequest );
00647 case ConfigureRequest:
00648 configureRequestEvent( &e->xconfigurerequest );
00649 break;
00650 case PropertyNotify:
00651 propertyNotifyEvent( &e->xproperty );
00652 break;
00653 case KeyPress:
00654 updateUserTime();
00655 workspace()->setWasUserInteraction();
00656 break;
00657 case ButtonPress:
00658 updateUserTime();
00659 workspace()->setWasUserInteraction();
00660 buttonPressEvent( e->xbutton.window, e->xbutton.button, e->xbutton.state,
00661 e->xbutton.x, e->xbutton.y, e->xbutton.x_root, e->xbutton.y_root );
00662 break;
00663 case KeyRelease:
00664
00665
00666
00667 break;
00668 case ButtonRelease:
00669
00670
00671
00672 buttonReleaseEvent( e->xbutton.window, e->xbutton.button, e->xbutton.state,
00673 e->xbutton.x, e->xbutton.y, e->xbutton.x_root, e->xbutton.y_root );
00674 break;
00675 case MotionNotify:
00676 motionNotifyEvent( e->xmotion.window, e->xmotion.state,
00677 e->xmotion.x, e->xmotion.y, e->xmotion.x_root, e->xmotion.y_root );
00678 workspace()->updateFocusMousePosition( QPoint( e->xmotion.x_root, e->xmotion.y_root ));
00679 break;
00680 case EnterNotify:
00681 enterNotifyEvent( &e->xcrossing );
00682
00683
00684
00685
00686
00687 motionNotifyEvent( e->xcrossing.window, e->xcrossing.state,
00688 e->xcrossing.x, e->xcrossing.y, e->xcrossing.x_root, e->xcrossing.y_root );
00689 workspace()->updateFocusMousePosition( QPoint( e->xcrossing.x_root, e->xcrossing.y_root ));
00690 break;
00691 case LeaveNotify:
00692 motionNotifyEvent( e->xcrossing.window, e->xcrossing.state,
00693 e->xcrossing.x, e->xcrossing.y, e->xcrossing.x_root, e->xcrossing.y_root );
00694 leaveNotifyEvent( &e->xcrossing );
00695
00696
00697 break;
00698 case FocusIn:
00699 focusInEvent( &e->xfocus );
00700 break;
00701 case FocusOut:
00702 focusOutEvent( &e->xfocus );
00703 break;
00704 case ReparentNotify:
00705 break;
00706 case ClientMessage:
00707 clientMessageEvent( &e->xclient );
00708 break;
00709 case ColormapChangeMask:
00710 if( e->xany.window == window())
00711 {
00712 cmap = e->xcolormap.colormap;
00713 if ( isActive() )
00714 workspace()->updateColormap();
00715 }
00716 break;
00717 default:
00718 if( e->xany.window == window())
00719 {
00720 if( e->type == Extensions::shapeNotifyEvent() )
00721 {
00722 detectShape( window());
00723 updateShape();
00724 }
00725 }
00726 if( e->xany.window == frameId())
00727 {
00728 #ifdef HAVE_XDAMAGE
00729 if( e->type == Extensions::damageNotifyEvent())
00730 damageNotifyEvent( reinterpret_cast< XDamageNotifyEvent* >( e ));
00731 #endif
00732 }
00733 break;
00734 }
00735 return true;
00736 }
00737
00741 bool Client::mapRequestEvent( XMapRequestEvent* e )
00742 {
00743 if( e->window != window())
00744 {
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757 if( e->parent == wrapperId())
00758 return false;
00759 return true;
00760 }
00761 if( isTopMenu() && workspace()->managingTopMenus())
00762 return true;
00763
00764 if( isMinimized())
00765 unminimize();
00766 if( isShade())
00767 setShade( ShadeNone );
00768 if( !isOnCurrentDesktop())
00769 {
00770 if( workspace()->allowClientActivation( this ))
00771 workspace()->activateClient( this );
00772 else
00773 demandAttention();
00774 }
00775 return true;
00776 }
00777
00781 void Client::unmapNotifyEvent( XUnmapEvent* e )
00782 {
00783 if( e->window != window())
00784 return;
00785 if( e->event != wrapperId())
00786 {
00787 bool ignore = true;
00788 if( e->event == rootWindow() && e->send_event )
00789 ignore = false;
00790 if( ignore )
00791 return;
00792 }
00793 releaseWindow();
00794 }
00795
00796 void Client::destroyNotifyEvent( XDestroyWindowEvent* e )
00797 {
00798 if( e->window != window())
00799 return;
00800 destroyClient();
00801 }
00802
00803
00807 void Client::clientMessageEvent( XClientMessageEvent* e )
00808 {
00809 if( e->window != window())
00810 return;
00811
00812 if ( e->message_type == atoms->kde_wm_change_state )
00813 {
00814 if( isTopMenu() && workspace()->managingTopMenus())
00815 return;
00816 bool avoid_animation = ( e->data.l[ 1 ] );
00817 if( e->data.l[ 0 ] == IconicState )
00818 minimize();
00819 else if( e->data.l[ 0 ] == NormalState )
00820 {
00821 if( isMinimized())
00822 unminimize( avoid_animation );
00823 if( isShade())
00824 setShade( ShadeNone );
00825 if( !isOnCurrentDesktop())
00826 {
00827 if( workspace()->allowClientActivation( this ))
00828 workspace()->activateClient( this );
00829 else
00830 demandAttention();
00831 }
00832 }
00833 }
00834 else if ( e->message_type == atoms->wm_change_state)
00835 {
00836 if( isTopMenu() && workspace()->managingTopMenus())
00837 return;
00838 if ( e->data.l[0] == IconicState )
00839 minimize();
00840 return;
00841 }
00842 }
00843
00844
00848 void Client::configureRequestEvent( XConfigureRequestEvent* e )
00849 {
00850 if( e->window != window())
00851 return;
00852 if ( isResize() || isMove())
00853 return;
00854
00855 if( fullscreen_mode == FullScreenNormal )
00856 {
00857 sendSyntheticConfigureNotify();
00858 return;
00859 }
00860 if( isSplash()
00861 || isTopMenu())
00862 {
00863 sendSyntheticConfigureNotify();
00864 return;
00865 }
00866
00867 if ( e->value_mask & CWBorderWidth )
00868 {
00869
00870 XWindowChanges wc;
00871 unsigned int value_mask = 0;
00872
00873 wc.border_width = 0;
00874 value_mask = CWBorderWidth;
00875 XConfigureWindow( display(), window(), value_mask, & wc );
00876 }
00877
00878 if( e->value_mask & ( CWX | CWY | CWHeight | CWWidth ))
00879 configureRequest( e->value_mask, e->x, e->y, e->width, e->height, 0, false );
00880
00881 if ( e->value_mask & CWStackMode )
00882 restackWindow( e->above, e->detail, NET::FromApplication, userTime(), false );
00883
00884
00885
00886
00887
00888
00889 sendSyntheticConfigureNotify();
00890
00891
00892
00893 }
00894
00895
00899 void Client::propertyNotifyEvent( XPropertyEvent* e )
00900 {
00901 Toplevel::propertyNotifyEvent( e );
00902 if( e->window != window())
00903 return;
00904 switch ( e->atom )
00905 {
00906 case XA_WM_NORMAL_HINTS:
00907 getWmNormalHints();
00908 break;
00909 case XA_WM_NAME:
00910 fetchName();
00911 break;
00912 case XA_WM_ICON_NAME:
00913 fetchIconicName();
00914 break;
00915 case XA_WM_TRANSIENT_FOR:
00916 readTransient();
00917 break;
00918 case XA_WM_HINTS:
00919 getWMHints();
00920 getIcons();
00921 break;
00922 default:
00923 if ( e->atom == atoms->wm_protocols )
00924 getWindowProtocols();
00925 else if( e->atom == atoms->motif_wm_hints )
00926 getMotifHints();
00927 else if( e->atom == atoms->net_wm_sync_request_counter )
00928 getSyncCounter();
00929 break;
00930 }
00931 }
00932
00933
00934 void Client::enterNotifyEvent( XCrossingEvent* e )
00935 {
00936 if( e->window != frameId())
00937 return;
00938 if( e->mode == NotifyNormal ||
00939 ( !options->focusPolicyIsReasonable() &&
00940 e->mode == NotifyUngrab ) )
00941 {
00942
00943 if ( options->shadeHover )
00944 {
00945 cancelShadeHoverTimer();
00946 if (isShade())
00947 {
00948 shadeHoverTimer = new QTimer( this );
00949 connect( shadeHoverTimer, SIGNAL( timeout() ), this, SLOT( shadeHover() ));
00950 shadeHoverTimer->setSingleShot( true );
00951 shadeHoverTimer->start( options->shadeHoverInterval );
00952 }
00953 }
00954
00955 if ( options->focusPolicy == Options::ClickToFocus )
00956 return;
00957
00958 if ( options->autoRaise && !isDesktop() &&
00959 !isDock() && !isTopMenu() && workspace()->focusChangeEnabled() &&
00960 workspace()->topClientOnDesktop( workspace()->currentDesktop(),
00961 options->separateScreenFocus ? screen() : -1 ) != this )
00962 {
00963 delete autoRaiseTimer;
00964 autoRaiseTimer = new QTimer( this );
00965 connect( autoRaiseTimer, SIGNAL( timeout() ), this, SLOT( autoRaise() ) );
00966 autoRaiseTimer->setSingleShot( true );
00967 autoRaiseTimer->start( options->autoRaiseInterval );
00968 }
00969
00970 QPoint currentPos( e->x_root, e->y_root );
00971 if ( options->focusPolicy != Options::FocusStrictlyUnderMouse && ( isDesktop() || isDock() || isTopMenu() ) )
00972 return;
00973
00974
00975 if( options->focusPolicy != Options::FocusFollowsMouse
00976 || currentPos != workspace()->focusMousePosition())
00977 {
00978 if ( options->delayFocus )
00979 workspace()->requestDelayFocus( this );
00980 else
00981 workspace()->requestFocus( this );
00982 }
00983 return;
00984 }
00985 }
00986
00987 void Client::leaveNotifyEvent( XCrossingEvent* e )
00988 {
00989 if( e->window != frameId())
00990 return;
00991 if ( e->mode == NotifyNormal )
00992 {
00993 if ( !buttonDown )
00994 {
00995 mode = PositionCenter;
00996 updateCursor();
00997 }
00998 bool lostMouse = !rect().contains( QPoint( e->x, e->y ) );
00999
01000
01001
01002
01003
01004
01005
01006 if ( !lostMouse && e->detail != NotifyInferior )
01007 {
01008 int d1, d2, d3, d4;
01009 unsigned int d5;
01010 Window w, child;
01011 if( XQueryPointer( display(), frameId(), &w, &child, &d1, &d2, &d3, &d4, &d5 ) == False
01012 || child == None )
01013 lostMouse = true;
01014 }
01015 if ( lostMouse )
01016 {
01017 cancelAutoRaise();
01018 workspace()->cancelDelayFocus();
01019 cancelShadeHoverTimer();
01020 if ( shade_mode == ShadeHover && !moveResizeMode && !buttonDown )
01021 {
01022 shadeHoverTimer = new QTimer( this );
01023 connect( shadeHoverTimer, SIGNAL( timeout() ), this, SLOT( shadeUnhover() ));
01024 shadeHoverTimer->setSingleShot( true );
01025 shadeHoverTimer->start( options->shadeHoverInterval );
01026 }
01027 }
01028 if ( options->focusPolicy == Options::FocusStrictlyUnderMouse )
01029 if ( isActive() && lostMouse )
01030 workspace()->requestFocus( 0 ) ;
01031 return;
01032 }
01033 }
01034
01035 #define XCapL KKeyServer::modXLock()
01036 #define XNumL KKeyServer::modXNumLock()
01037 #define XScrL KKeyServer::modXScrollLock()
01038 void Client::grabButton( int modifier )
01039 {
01040 unsigned int mods[ 8 ] =
01041 {
01042 0, XCapL, XNumL, XNumL | XCapL,
01043 XScrL, XScrL | XCapL,
01044 XScrL | XNumL, XScrL | XNumL | XCapL
01045 };
01046 for( int i = 0;
01047 i < 8;
01048 ++i )
01049 XGrabButton( display(), AnyButton,
01050 modifier | mods[ i ],
01051 wrapperId(), false, ButtonPressMask,
01052 GrabModeSync, GrabModeAsync, None, None );
01053 }
01054
01055 void Client::ungrabButton( int modifier )
01056 {
01057 unsigned int mods[ 8 ] =
01058 {
01059 0, XCapL, XNumL, XNumL | XCapL,
01060 XScrL, XScrL | XCapL,
01061 XScrL | XNumL, XScrL | XNumL | XCapL
01062 };
01063 for( int i = 0;
01064 i < 8;
01065 ++i )
01066 XUngrabButton( display(), AnyButton,
01067 modifier | mods[ i ], wrapperId());
01068 }
01069 #undef XCapL
01070 #undef XNumL
01071 #undef XScrL
01072
01073
01074
01075
01076
01077
01078
01079 void Client::updateMouseGrab()
01080 {
01081 if( workspace()->globalShortcutsDisabled())
01082 {
01083 XUngrabButton( display(), AnyButton, AnyModifier, wrapperId());
01084
01085 bool not_obscured = workspace()->topClientOnDesktop( workspace()->currentDesktop(), -1, true, false ) == this;
01086 if( !( !options->clickRaise || not_obscured ))
01087 grabButton( None );
01088 return;
01089 }
01090 if( isActive() && !workspace()->forcedGlobalMouseGrab())
01091 {
01092
01093 XGrabButton( display(), AnyButton, AnyModifier, wrapperId(), false,
01094 ButtonPressMask,
01095 GrabModeSync, GrabModeAsync,
01096 None, None );
01097
01098
01099
01100
01101 bool not_obscured = workspace()->topClientOnDesktop( workspace()->currentDesktop(), -1, true, false ) == this;
01102 if( !options->clickRaise || not_obscured )
01103 ungrabButton( None );
01104 else
01105 grabButton( None );
01106 ungrabButton( ShiftMask );
01107 ungrabButton( ControlMask );
01108 ungrabButton( ControlMask | ShiftMask );
01109 }
01110 else
01111 {
01112 XUngrabButton( display(), AnyButton, AnyModifier, wrapperId());
01113
01114 XGrabButton(display(), AnyButton, AnyModifier, wrapperId(), false,
01115 ButtonPressMask,
01116 GrabModeSync, GrabModeAsync,
01117 None, None );
01118 }
01119 }
01120
01121
01122
01123 bool Client::eventFilter( QObject* o, QEvent* e )
01124 {
01125 if( decoration == NULL
01126 || o != decoration->widget())
01127 return false;
01128 if( e->type() == QEvent::MouseButtonPress )
01129 {
01130 QMouseEvent* ev = static_cast< QMouseEvent* >( e );
01131 return buttonPressEvent( decorationId(), qtToX11Button( ev->button()), qtToX11State( ev->buttons(), ev->modifiers() ),
01132 ev->x(), ev->y(), ev->globalX(), ev->globalY() );
01133 }
01134 if( e->type() == QEvent::MouseButtonRelease )
01135 {
01136 QMouseEvent* ev = static_cast< QMouseEvent* >( e );
01137 return buttonReleaseEvent( decorationId(), qtToX11Button( ev->button()), qtToX11State( ev->buttons(), ev->modifiers() ),
01138 ev->x(), ev->y(), ev->globalX(), ev->globalY() );
01139 }
01140 if( e->type() == QEvent::MouseMove )
01141 {
01142 QMouseEvent* ev = static_cast< QMouseEvent* >( e );
01143 return motionNotifyEvent( decorationId(), qtToX11State( ev->buttons(), ev->modifiers() ),
01144 ev->x(), ev->y(), ev->globalX(), ev->globalY() );
01145 }
01146 if( e->type() == QEvent::Wheel )
01147 {
01148 QWheelEvent* ev = static_cast< QWheelEvent* >( e );
01149 bool r = buttonPressEvent( decorationId(), ev->delta() > 0 ? Button4 : Button5, qtToX11State( ev->buttons(), ev->modifiers() ),
01150 ev->x(), ev->y(), ev->globalX(), ev->globalY() );
01151 r = r || buttonReleaseEvent( decorationId(), ev->delta() > 0 ? Button4 : Button5, qtToX11State( ev->buttons(), ev->modifiers() ),
01152 ev->x(), ev->y(), ev->globalX(), ev->globalY() );
01153 return r;
01154 }
01155 if( e->type() == QEvent::Resize )
01156 {
01157 QResizeEvent* ev = static_cast< QResizeEvent* >( e );
01158
01159
01160
01161
01162 if( ev->size() != size())
01163 return true;
01164
01165
01166
01167
01168
01169
01170 decoration->widget()->setAttribute( Qt::WA_WState_ConfigPending, false );
01171 decoration->widget()->update();
01172 return false;
01173 }
01174 return false;
01175 }
01176
01177
01178 bool Client::buttonPressEvent( Window w, int button, int state, int x, int y, int x_root, int y_root )
01179 {
01180 if (buttonDown)
01181 {
01182 if( w == wrapperId())
01183 XAllowEvents(display(), SyncPointer, CurrentTime );
01184 return true;
01185 }
01186
01187 if( w == wrapperId() || w == frameId() || w == decorationId())
01188 {
01189 updateUserTime();
01190 workspace()->setWasUserInteraction();
01191 uint keyModX = (options->keyCmdAllModKey() == Qt::Key_Meta) ?
01192 KKeyServer::modXMeta() :
01193 KKeyServer::modXAlt();
01194 bool bModKeyHeld = keyModX != 0 && ( state & KKeyServer::accelModMaskX()) == keyModX;
01195
01196 if( isSplash()
01197 && button == Button1 && !bModKeyHeld )
01198 {
01199 hideClient( true );
01200 if( w == wrapperId())
01201 XAllowEvents(display(), SyncPointer, CurrentTime );
01202 return true;
01203 }
01204
01205 Options::MouseCommand com = Options::MouseNothing;
01206 bool was_action = false;
01207 bool perform_handled = false;
01208 if ( bModKeyHeld )
01209 {
01210 was_action = true;
01211 switch (button)
01212 {
01213 case Button1:
01214 com = options->commandAll1();
01215 break;
01216 case Button2:
01217 com = options->commandAll2();
01218 break;
01219 case Button3:
01220 com = options->commandAll3();
01221 break;
01222 case Button4:
01223 case Button5:
01224 com = options->operationWindowMouseWheel( button == Button4 ? 120 : -120 );
01225 break;
01226 }
01227 }
01228 else
01229 {
01230 if( !isActive() && w == wrapperId() && button < 4 )
01231 {
01232 was_action = true;
01233 perform_handled = true;
01234 switch (button)
01235 {
01236 case Button1:
01237 com = options->commandWindow1();
01238 break;
01239 case Button2:
01240 com = options->commandWindow2();
01241 break;
01242 case Button3:
01243 com = options->commandWindow3();
01244 break;
01245 }
01246 }
01247
01248 if( isActive() && w == wrapperId()
01249 && options->clickRaise && button < 4 )
01250 {
01251 com = Options::MouseActivateRaiseAndPassClick;
01252 was_action = true;
01253 perform_handled = true;
01254 }
01255 }
01256 if( was_action )
01257 {
01258 bool replay = performMouseCommand( com, QPoint( x_root, y_root), perform_handled );
01259
01260 if ( isSpecialWindow())
01261 replay = true;
01262
01263 if( w == wrapperId())
01264 XAllowEvents(display(), replay? ReplayPointer : SyncPointer, CurrentTime );
01265 return true;
01266 }
01267 }
01268
01269 if( w == wrapperId())
01270 {
01271 XAllowEvents(display(), ReplayPointer, CurrentTime );
01272 return true;
01273 }
01274 if( w == decorationId())
01275 return false;
01276 if( w == frameId())
01277 processDecorationButtonPress( button, state, x, y, x_root, y_root );
01278 return true;
01279 }
01280
01281
01282
01283
01284 void Client::processDecorationButtonPress( int button, int , int x, int y, int x_root, int y_root )
01285 {
01286 Options::MouseCommand com = Options::MouseNothing;
01287 bool active = isActive();
01288 if ( !wantsInput() )
01289 active = true;
01290
01291 if ( button == Button1 )
01292 com = active ? options->commandActiveTitlebar1() : options->commandInactiveTitlebar1();
01293 else if ( button == Button2 )
01294 com = active ? options->commandActiveTitlebar2() : options->commandInactiveTitlebar2();
01295 else if ( button == Button3 )
01296 com = active ? options->commandActiveTitlebar3() : options->commandInactiveTitlebar3();
01297 if( button == Button1
01298 && com != Options::MouseOperationsMenu
01299 && com != Options::MouseMinimize )
01300 {
01301 mode = mousePosition( QPoint( x, y ));
01302 buttonDown = true;
01303 moveOffset = QPoint( x, y );
01304 invertedMoveOffset = rect().bottomRight() - moveOffset;
01305 unrestrictedMoveResize = false;
01306 startDelayedMoveResize();
01307 updateCursor();
01308 }
01309 performMouseCommand( com, QPoint( x_root, y_root ));
01310 }
01311
01312
01313 void Client::processMousePressEvent( QMouseEvent* e )
01314 {
01315 if( e->type() != QEvent::MouseButtonPress )
01316 {
01317 kWarning(1212) << "processMousePressEvent()" ;
01318 return;
01319 }
01320 int button;
01321 switch( e->button())
01322 {
01323 case Qt::LeftButton:
01324 button = Button1;
01325 break;
01326 case Qt::MidButton:
01327 button = Button2;
01328 break;
01329 case Qt::RightButton:
01330 button = Button3;
01331 break;
01332 default:
01333 return;
01334 }
01335 processDecorationButtonPress( button, e->buttons(), e->x(), e->y(), e->globalX(), e->globalY());
01336 }
01337
01338
01339 bool Client::buttonReleaseEvent( Window w, int , int state, int x, int y, int x_root, int y_root )
01340 {
01341 if( w == decorationId() && !buttonDown)
01342 return false;
01343 if( w == wrapperId())
01344 {
01345 XAllowEvents(display(), SyncPointer, CurrentTime );
01346 return true;
01347 }
01348 if( w != frameId() && w != decorationId() && w != moveResizeGrabWindow())
01349 return true;
01350 x = this->x();
01351 y = this->y();
01352 if ( (state & ( Button1Mask & Button2Mask & Button3Mask )) == 0 )
01353 {
01354 buttonDown = false;
01355 stopDelayedMoveResize();
01356 if ( moveResizeMode )
01357 {
01358 finishMoveResize( false );
01359
01360 QPoint mousepos( x_root - x, y_root - y );
01361 mode = mousePosition( mousepos );
01362 }
01363 updateCursor();
01364 }
01365 return true;
01366 }
01367
01368 static bool was_motion = false;
01369 static Time next_motion_time = CurrentTime;
01370
01371
01372
01373
01374
01375
01376
01377 static Bool motion_predicate( Display*, XEvent* ev, XPointer )
01378 {
01379 if( ev->type == MotionNotify )
01380 {
01381 was_motion = true;
01382 next_motion_time = ev->xmotion.time;
01383 }
01384 return False;
01385 }
01386
01387 static bool waitingMotionEvent()
01388 {
01389
01390
01391
01392 if( next_motion_time != CurrentTime
01393 && timestampCompare( xTime(), next_motion_time ) < 0 )
01394 return true;
01395 was_motion = false;
01396 XSync( display(), False );
01397 XEvent dummy;
01398 XCheckIfEvent( display(), &dummy, motion_predicate, NULL );
01399 return was_motion;
01400 }
01401
01402
01403 bool Client::motionNotifyEvent( Window w, int , int x, int y, int x_root, int y_root )
01404 {
01405 if( w != frameId() && w != decorationId() && w != moveResizeGrabWindow())
01406 return true;
01407 if ( !buttonDown )
01408 {
01409 Position newmode = mousePosition( QPoint( x, y ));
01410 if( newmode != mode )
01411 {
01412 mode = newmode;
01413 updateCursor();
01414 }
01415
01416
01417 next_motion_time = CurrentTime;
01418 return false;
01419 }
01420 if( w == moveResizeGrabWindow())
01421 {
01422 x = this->x();
01423 y = this->y();
01424 }
01425 if( !waitingMotionEvent())
01426 handleMoveResize( x, y, x_root, y_root );
01427 return true;
01428 }
01429
01430 void Client::focusInEvent( XFocusInEvent* e )
01431 {
01432 if( e->window != window())
01433 return;
01434 if ( e->mode == NotifyUngrab )
01435 return;
01436 if ( e->detail == NotifyPointer )
01437 return;
01438 if( !isShown( false ) || !isOnCurrentDesktop())
01439 return;
01440
01441 bool activate = workspace()->allowClientActivation( this, -1U, true );
01442 workspace()->gotFocusIn( this );
01443 if( activate )
01444 setActive( true );
01445 else
01446 {
01447 workspace()->restoreFocus();
01448 demandAttention();
01449 }
01450 }
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466 static bool follows_focusin = false;
01467 static bool follows_focusin_failed = false;
01468 static Bool predicate_follows_focusin( Display*, XEvent* e, XPointer arg )
01469 {
01470 if( follows_focusin || follows_focusin_failed )
01471 return False;
01472 Client* c = ( Client* ) arg;
01473 if( e->type == FocusIn && c->workspace()->findClient( WindowMatchPredicate( e->xfocus.window )))
01474 {
01475 follows_focusin = true;
01476 return False;
01477 }
01478
01479
01480 if( e->type == FocusIn || e->type == FocusOut || e->type == KeymapNotify )
01481 return False;
01482 follows_focusin_failed = true;
01483 return False;
01484 }
01485
01486 static bool check_follows_focusin( Client* c )
01487 {
01488 follows_focusin = follows_focusin_failed = false;
01489 XEvent dummy;
01490
01491
01492
01493 XCheckIfEvent( display(), &dummy, predicate_follows_focusin, (XPointer)c );
01494 return follows_focusin;
01495 }
01496
01497
01498 void Client::focusOutEvent( XFocusOutEvent* e )
01499 {
01500 if( e->window != window())
01501 return;
01502 if ( e->mode == NotifyGrab )
01503 return;
01504 if ( isShade() )
01505 return;
01506 if ( e->detail != NotifyNonlinear
01507 && e->detail != NotifyNonlinearVirtual )
01508
01509 return;
01510 if ( QApplication::activePopupWidget() )
01511 return;
01512 if( !check_follows_focusin( this ))
01513 setActive( false );
01514 }
01515
01516
01517 void Client::NETMoveResize( int x_root, int y_root, NET::Direction direction )
01518 {
01519 if( direction == NET::Move )
01520 performMouseCommand( Options::MouseMove, QPoint( x_root, y_root ));
01521 else if( moveResizeMode && direction == NET::MoveResizeCancel)
01522 {
01523 finishMoveResize( true );
01524 buttonDown = false;
01525 updateCursor();
01526 }
01527 else if( direction >= NET::TopLeft && direction <= NET::Left )
01528 {
01529 static const Position convert[] =
01530 {
01531 PositionTopLeft,
01532 PositionTop,
01533 PositionTopRight,
01534 PositionRight,
01535 PositionBottomRight,
01536 PositionBottom,
01537 PositionBottomLeft,
01538 PositionLeft
01539 };
01540 if(!isResizable() || isShade())
01541 return;
01542 if( moveResizeMode )
01543 finishMoveResize( false );
01544 buttonDown = true;
01545 moveOffset = QPoint( x_root - x(), y_root - y());
01546 invertedMoveOffset = rect().bottomRight() - moveOffset;
01547 unrestrictedMoveResize = false;
01548 mode = convert[ direction ];
01549 if( !startMoveResize())
01550 buttonDown = false;
01551 updateCursor();
01552 }
01553 else if( direction == NET::KeyboardMove )
01554 {
01555 QCursor::setPos( geometry().center() );
01556 performMouseCommand( Options::MouseUnrestrictedMove, geometry().center());
01557 }
01558 else if( direction == NET::KeyboardSize )
01559 {
01560 QCursor::setPos( geometry().bottomRight());
01561 performMouseCommand( Options::MouseUnrestrictedResize, geometry().bottomRight());
01562 }
01563 }
01564
01565 void Client::keyPressEvent( uint key_code )
01566 {
01567 updateUserTime();
01568 if ( !isMove() && !isResize() )
01569 return;
01570 bool is_control = key_code & Qt::CTRL;
01571 bool is_alt = key_code & Qt::ALT;
01572 key_code = key_code & ~Qt::KeyboardModifierMask;
01573 int delta = is_control?1:is_alt?32:8;
01574 QPoint pos = cursorPos();
01575 switch ( key_code )
01576 {
01577 case Qt::Key_Left:
01578 pos.rx() -= delta;
01579 break;
01580 case Qt::Key_Right:
01581 pos.rx() += delta;
01582 break;
01583 case Qt::Key_Up:
01584 pos.ry() -= delta;
01585 break;
01586 case Qt::Key_Down:
01587 pos.ry() += delta;
01588 break;
01589 case Qt::Key_Space:
01590 case Qt::Key_Return:
01591 case Qt::Key_Enter:
01592 finishMoveResize( false );
01593 buttonDown = false;
01594 updateCursor();
01595 break;
01596 case Qt::Key_Escape:
01597 finishMoveResize( true );
01598 buttonDown = false;
01599 updateCursor();
01600 break;
01601 default:
01602 return;
01603 }
01604 QCursor::setPos( pos );
01605 }
01606
01607 #ifdef HAVE_XSYNC
01608 void Client::syncEvent( XSyncAlarmNotifyEvent* e )
01609 {
01610 if( e->alarm == sync_alarm && XSyncValueEqual( e->counter_value, sync_counter_value ))
01611 {
01612 ready_for_painting = true;
01613 if( isResize())
01614 {
01615 delete sync_timeout;
01616 sync_timeout = NULL;
01617 if( sync_resize_pending )
01618 performMoveResize();
01619 }
01620 }
01621 }
01622 #endif
01623
01624
01625
01626
01627
01628 bool Unmanaged::windowEvent( XEvent* e )
01629 {
01630 double old_opacity = opacity();
01631 unsigned long dirty[ 2 ];
01632 info->event( e, dirty, 2 );
01633 if( dirty[ NETWinInfo::PROTOCOLS2 ] & NET::WM2Opacity )
01634 {
01635 if( compositing())
01636 {
01637 addRepaintFull();
01638 scene->windowOpacityChanged( this );
01639 if( effects )
01640 static_cast<EffectsHandlerImpl*>(effects)->windowOpacityChanged( effectWindow(), old_opacity );
01641 }
01642 }
01643 switch (e->type)
01644 {
01645 case UnmapNotify:
01646 unmapNotifyEvent( &e->xunmap );
01647 break;
01648 case MapNotify:
01649 mapNotifyEvent( &e->xmap );
01650 break;
01651 case ConfigureNotify:
01652 configureNotifyEvent( &e->xconfigure );
01653 break;
01654 case PropertyNotify:
01655 propertyNotifyEvent( &e->xproperty );
01656 break;
01657 default:
01658 {
01659 if( e->type == Extensions::shapeNotifyEvent() )
01660 {
01661 detectShape( window());
01662 addRepaintFull();
01663 addWorkspaceRepaint( geometry());
01664 if( scene != NULL )
01665 scene->windowGeometryShapeChanged( this );
01666 if( effects != NULL )
01667 static_cast<EffectsHandlerImpl*>(effects)->windowGeometryShapeChanged( effectWindow(), geometry());
01668 }
01669 #ifdef HAVE_XDAMAGE
01670 if( e->type == Extensions::damageNotifyEvent())
01671 damageNotifyEvent( reinterpret_cast< XDamageNotifyEvent* >( e ));
01672 #endif
01673 break;
01674 }
01675 }
01676 return false;
01677 }
01678
01679 void Unmanaged::mapNotifyEvent( XMapEvent* )
01680 {
01681 }
01682
01683 void Unmanaged::unmapNotifyEvent( XUnmapEvent* )
01684 {
01685 release();
01686 }
01687
01688 void Unmanaged::configureNotifyEvent( XConfigureEvent* e )
01689 {
01690 if( effects )
01691 static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowStacking();
01692 QRect newgeom( e->x, e->y, e->width, e->height );
01693 if( newgeom != geom )
01694 {
01695 addWorkspaceRepaint( geometry());
01696 QRect old = geom;
01697 geom = newgeom;
01698 addRepaintFull();
01699 if( old.size() != geom.size())
01700 discardWindowPixmap();
01701 if( scene != NULL )
01702 scene->windowGeometryShapeChanged( this );
01703 if( effects != NULL )
01704 static_cast<EffectsHandlerImpl*>(effects)->windowGeometryShapeChanged( effectWindow(), old );
01705 }
01706 }
01707
01708
01709
01710
01711
01712 void Toplevel::propertyNotifyEvent( XPropertyEvent* e )
01713 {
01714 if( e->window != window())
01715 return;
01716 switch ( e->atom )
01717 {
01718 default:
01719 if (e->atom == atoms->wm_client_leader )
01720 getWmClientLeader();
01721 else if( e->atom == atoms->wm_window_role )
01722 getWindowRole();
01723 break;
01724 }
01725 if( effects )
01726 static_cast< EffectsHandlerImpl* >( effects )->propertyNotify( effectWindow(), e->atom );
01727 }
01728
01729
01730
01731
01732
01733 bool Group::groupEvent( XEvent* e )
01734 {
01735 unsigned long dirty[ 2 ];
01736 leader_info->event( e, dirty, 2 );
01737 if ( ( dirty[ WinInfo::PROTOCOLS ] & NET::WMIcon) != 0 )
01738 getIcons();
01739 if(( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2StartupId ) != 0 )
01740 startupIdChanged();
01741 return false;
01742 }
01743
01744
01745 }