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