diff --git a/events.cpp b/events.cpp index 8043a95b72..9ed44f84a6 100644 --- a/events.cpp +++ b/events.cpp @@ -21,9 +21,6 @@ License. See the file "COPYING" for the exact licensing terms. #include "tabbox.h" #include "group.h" #include "rules.h" -#include "unmanaged.h" -#include "scene.h" -#include "effects.h" #include #include @@ -86,10 +83,6 @@ void WinInfo::changeState( unsigned long state, unsigned long mask ) m_client->setFullScreen( true, false ); } -void WinInfo::disable() - { - m_client = NULL; // only used when the object is passed to Deleted - } // **************************************** // RootInfo @@ -206,10 +199,15 @@ bool Workspace::workspaceEvent( XEvent * e ) XUngrabKeyboard( display(), xTime() ); } - if ( e->type == PropertyNotify || e->type == ClientMessage ) + if( e->type == PropertyNotify || e->type == ClientMessage ) { - if ( netCheck( e ) ) - return true; + unsigned long dirty[ NETRootInfo::PROPERTIES_SIZE ]; + rootInfo->event( e, dirty, NETRootInfo::PROPERTIES_SIZE ); + if( dirty[ NETRootInfo::PROTOCOLS ] & NET::DesktopNames ) + saveDesktopSettings(); + if( dirty[ NETRootInfo::PROTOCOLS2 ] & NET::WM2DesktopLayout ) + setDesktopLayout( rootInfo->desktopLayoutOrientation(), rootInfo->desktopLayoutColumnsRows().width(), + rootInfo->desktopLayoutColumnsRows().height(), rootInfo->desktopLayoutCorner()); } // events that should be handled before Clients can get them @@ -225,14 +223,12 @@ bool Workspace::workspaceEvent( XEvent * e ) tab_box->handleMouseEvent( e ); return true; } - if( effects && effects->checkInputWindowEvent( e )) - return true; break; case KeyPress: { was_user_interaction = true; int keyQt; - KKeyServer::xEventToQt(e, keyQt); + KKeyServer::xEventToQt(e, &keyQt); kDebug(125) << "Workspace::keyPress( " << keyQt << " )" << endl; if (movingClient) { @@ -271,11 +267,6 @@ bool Workspace::workspaceEvent( XEvent * e ) if( c->windowEvent( e )) return true; } - else if( Unmanaged* c = findUnmanaged( WindowMatchPredicate( e->xany.window ))) - { - if( c->windowEvent( e )) - return true; - } else { Window special = findSpecialEventWindow( e ); @@ -333,8 +324,13 @@ bool Workspace::workspaceEvent( XEvent * e ) } return true; } + return ( e->xunmap.event != e->xunmap.window ); // hide wm typical event from Qt } + case MapNotify: + + return ( e->xmap.event != e->xmap.window ); // hide wm typical event from Qt + case ReparentNotify: { //do not confuse Qt with these events. After all, _we_ are the @@ -384,19 +380,6 @@ bool Workspace::workspaceEvent( XEvent * e ) } break; } - case MapNotify: - { - if( e->xmap.override_redirect ) - { - Unmanaged* c = findUnmanaged( WindowMatchPredicate( e->xmap.window )); - if( c == NULL ) - c = createUnmanaged( e->xmap.window ); - if( c ) - return c->windowEvent( e ); - } - return ( e->xmap.event != e->xmap.window ); // hide wm typical event from Qt - } - case EnterNotify: { if ( QWhatsThis::inWhatsThisMode() ) @@ -473,29 +456,7 @@ bool Workspace::workspaceEvent( XEvent * e ) if( electricBorder( e )) return true; break; - case MappingNotify: - XRefreshKeyboardMapping( &e->xmapping ); - tab_box->updateKeyMapping(); - break; - case Expose: - if( e->xexpose.window == rootWindow() && compositing()) // root window needs repainting - addRepaint( e->xexpose.x, e->xexpose.y, e->xexpose.width, e->xexpose.height ); - break; default: - if( e->type == Extensions::randrNotifyEvent() && Extensions::randrAvailable() ) - { -#ifdef HAVE_XRANDR - XRRUpdateConfiguration( e ); -#endif - if( compositing() ) - { - // desktopResized() should take care of when the size or - // shape of the desktop has changed, but we also want to - // catch refresh rate changes - finishCompositing(); - QTimer::singleShot( 0, this, SLOT( setupCompositing() ) ); - } - } break; } return false; @@ -535,20 +496,6 @@ Window Workspace::findSpecialEventWindow( XEvent* e ) }; } -/*! - Handles client messages sent to the workspace - */ -bool Workspace::netCheck( XEvent* e ) - { - unsigned int dirty = rootInfo->event( e ); - - if ( dirty & NET::DesktopNames ) - saveDesktopSettings(); - - return dirty != 0; - } - - // **************************************** // Client // **************************************** @@ -561,7 +508,6 @@ bool Client::windowEvent( XEvent* e ) if( e->xany.window == window()) // avoid doing stuff on frame or wrapper { unsigned long dirty[ 2 ]; - double old_opacity = opacity(); info->event( e, dirty, 2 ); // pass through the NET stuff if ( ( dirty[ WinInfo::PROTOCOLS ] & NET::WMName ) != 0 ) @@ -592,21 +538,6 @@ bool Client::windowEvent( XEvent* e ) if( demandAttentionKNotifyTimer != NULL ) demandAttentionKNotify(); } - if( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2Opacity ) - { - if( compositing()) - { - addRepaintFull(); - scene->windowOpacityChanged( this ); - if( effects ) - effects->windowOpacityChanged( effectWindow(), old_opacity ); - } - else - { // forward to the frame if there's possibly another compositing manager running - NETWinInfo i( display(), frameId(), rootWindow(), 0 ); - i.setOpacity( info->opacity()); - } - } } // TODO move all focus handling stuff to separate file? @@ -687,25 +618,15 @@ bool Client::windowEvent( XEvent* e ) workspace()->updateColormap(); } break; - case VisibilityNotify: - visibilityNotifyEvent( &e->xvisibility ); - break; default: if( e->xany.window == window()) + { + if( e->type == Shape::shapeEvent() ) { - if( e->type == Extensions::shapeNotifyEvent() ) - { - detectShape( window()); // workaround for #19644 - updateShape(); - } - } - if( e->xany.window == frameId()) - { -#ifdef HAVE_XDAMAGE - if( e->type == Extensions::damageNotifyEvent()) - damageNotifyEvent( reinterpret_cast< XDamageNotifyEvent* >( e )); -#endif + is_shape = Shape::hasShape( window()); // workaround for #19644 + updateShape(); } + } break; } return true; // eat all events @@ -807,6 +728,8 @@ void Client::destroyNotifyEvent( XDestroyWindowEvent* e ) } +bool blockAnimation = false; + /*! Handles client messages for the client window */ @@ -819,13 +742,14 @@ void Client::clientMessageEvent( XClientMessageEvent* e ) { if( isTopMenu() && workspace()->managingTopMenus()) return; // kwin controls these - bool avoid_animation = ( e->data.l[ 1 ] ); + if( e->data.l[ 1 ] ) + blockAnimation = true; if( e->data.l[ 0 ] == IconicState ) minimize(); else if( e->data.l[ 0 ] == NormalState ) { // copied from mapRequest() if( isMinimized()) - unminimize( avoid_animation ); + unminimize(); if( isShade()) setShade( ShadeNone ); if( !isOnCurrentDesktop()) @@ -836,6 +760,7 @@ void Client::clientMessageEvent( XClientMessageEvent* e ) demandAttention(); } } + blockAnimation = false; } else if ( e->message_type == atoms->wm_change_state) { @@ -904,7 +829,6 @@ void Client::configureRequestEvent( XConfigureRequestEvent* e ) */ void Client::propertyNotifyEvent( XPropertyEvent* e ) { - Toplevel::propertyNotifyEvent( e ); if( e->window != window()) return; // ignore frame/wrapper switch ( e->atom ) @@ -928,6 +852,10 @@ void Client::propertyNotifyEvent( XPropertyEvent* e ) default: if ( e->atom == atoms->wm_protocols ) getWindowProtocols(); + else if (e->atom == atoms->wm_client_leader ) + getWmClientLeader(); + else if( e->atom == atoms->wm_window_role ) + window_role = staticWindowRole( window()); else if( e->atom == atoms->motif_wm_hints ) getMotifHints(); break; @@ -1067,18 +995,13 @@ void Client::ungrabButton( int modifier ) */ void Client::updateMouseGrab() { - if( workspace()->globalShortcutsDisabled()) - { - XUngrabButton( display(), AnyButton, AnyModifier, wrapperId()); - // keep grab for the simple click without modifiers if needed - if( !( !options->clickRaise || not_obscured )) - grabButton( None ); - return; - } if( isActive() && !workspace()->forcedGlobalMouseGrab()) // see Workspace::establishTabBoxGrab() { // remove the grab for no modifiers only if the window // is unobscured or if the user doesn't want click raise + // (it is unobscured if it the topmost in the unconstrained stacking order, i.e. it is + // the most recently raised window) + bool not_obscured = workspace()->topClientOnDesktop( workspace()->currentDesktop(), true, false ) == this; if( !options->clickRaise || not_obscured ) ungrabButton( None ); else @@ -1098,6 +1021,37 @@ void Client::updateMouseGrab() } } +int qtToX11Button( Qt::ButtonState button ) + { + if( button == Qt::LeftButton ) + return Button1; + else if( button == Qt::MidButton ) + return Button2; + else if( button == Qt::RightButton ) + return Button3; + return AnyButton; + } + +int qtToX11State( Qt::ButtonState buttons, Qt::KeyboardModifiers modifiers ) + { + int ret = 0; + if( buttons & Qt::LeftButton ) + ret |= Button1Mask; + if( buttons & Qt::MidButton ) + ret |= Button2Mask; + if( buttons & Qt::RightButton ) + ret |= Button3Mask; + if( modifiers & Qt::ShiftModifier ) + ret |= ShiftMask; + if( modifiers & Qt::ControlModifier ) + ret |= ControlMask; + if( modifiers & Qt::AltModifier ) + ret |= KKeyServer::modXAlt(); + if( modifiers & Qt::MetaModifier ) + ret |= KKeyServer::modXMeta(); + return ret; + } + // Qt propagates mouse events up the widget hierachy, which means events // for the decoration window cannot be (easily) intercepted as X11 events bool Client::eventFilter( QObject* o, QEvent* e ) @@ -1141,15 +1095,6 @@ bool Client::eventFilter( QObject* o, QEvent* e ) // on the decoration widget. if( ev->size() != size()) return true; - // HACK: Avoid decoration redraw delays. On resize Qt sets WA_WStateConfigPending - // which delays all painting until a matching ConfigureNotify event comes. - // But this process itself is the window manager, so it's not needed - // to wait for that event, the geometry is known. - // Note that if Qt in the future changes how this flag is handled and what it - // triggers then this may potentionally break things. See mainly QETWidget::translateConfigEvent(). - decoration->widget()->setAttribute( Qt::WA_WState_ConfigPending, false ); - decoration->widget()->update(); - return false; } return false; } @@ -1491,17 +1436,6 @@ void Client::focusOutEvent( XFocusOutEvent* e ) setActive( false ); } -void Client::visibilityNotifyEvent( XVisibilityEvent * e) - { - if( e->window != frameId()) - return; // care only about the whole frame - bool new_not_obscured = e->state == VisibilityUnobscured; - if( not_obscured == new_not_obscured ) - return; - not_obscured = new_not_obscured; - updateMouseGrab(); - } - // performs _NET_WM_MOVERESIZE void Client::NETMoveResize( int x_root, int y_root, NET::Direction direction ) { @@ -1563,7 +1497,7 @@ void Client::keyPressEvent( uint key_code ) bool is_alt = key_code & Qt::ALT; key_code = key_code & 0xffff; int delta = is_control?1:is_alt?32:8; - QPoint pos = cursorPos(); + QPoint pos = QCursor::pos(); switch ( key_code ) { case Qt::Key_Left: @@ -1596,104 +1530,6 @@ void Client::keyPressEvent( uint key_code ) QCursor::setPos( pos ); } -// **************************************** -// Unmanaged -// **************************************** - -bool Unmanaged::windowEvent( XEvent* e ) - { - double old_opacity = opacity(); - unsigned long dirty[ 2 ]; - info->event( e, dirty, 2 ); // pass through the NET stuff - if( dirty[ NETWinInfo::PROTOCOLS2 ] & NET::WM2Opacity ) - { - if( compositing()) - { - addRepaintFull(); - scene->windowOpacityChanged( this ); - if( effects ) - effects->windowOpacityChanged( effectWindow(), old_opacity ); - } - } - switch (e->type) - { - case UnmapNotify: - unmapNotifyEvent( &e->xunmap ); - break; - case MapNotify: - mapNotifyEvent( &e->xmap ); - break; - case ConfigureNotify: - configureNotifyEvent( &e->xconfigure ); - break; - case PropertyNotify: - propertyNotifyEvent( &e->xproperty ); - default: - { - if( e->type == Extensions::shapeNotifyEvent() ) - { - detectShape( window()); - addDamageFull(); - if( scene != NULL ) - scene->windowGeometryShapeChanged( this ); - if( effects != NULL ) - effects->windowGeometryShapeChanged( effectWindow(), geometry()); - } -#ifdef HAVE_XDAMAGE - if( e->type == Extensions::damageNotifyEvent()) - damageNotifyEvent( reinterpret_cast< XDamageNotifyEvent* >( e )); -#endif - break; - } - } - return false; // don't eat events, even our own unmanaged widgets are tracked - } - -void Unmanaged::mapNotifyEvent( XMapEvent* ) - { - } - -void Unmanaged::unmapNotifyEvent( XUnmapEvent* ) - { - release(); - } - -void Unmanaged::configureNotifyEvent( XConfigureEvent* e ) - { - if( effects ) - effects->checkInputWindowStacking(); // keep them on top - QRect newgeom( e->x, e->y, e->width, e->height ); - if( newgeom == geom ) - return; - addWorkspaceRepaint( geometry()); // damage old area - QRect old = geom; - geom = newgeom; - discardWindowPixmap(); - if( scene != NULL ) - scene->windowGeometryShapeChanged( this ); - if( effects != NULL ) - effects->windowGeometryShapeChanged( effectWindow(), old ); - } - -// **************************************** -// Toplevel -// **************************************** - -void Toplevel::propertyNotifyEvent( XPropertyEvent* e ) - { - if( e->window != window()) - return; // ignore frame/wrapper - switch ( e->atom ) - { - default: - if (e->atom == atoms->wm_client_leader ) - getWmClientLeader(); - else if( e->atom == atoms->wm_window_role ) - getWindowRole(); - break; - } - } - // **************************************** // Group // ****************************************