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