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