Support for effects taking control of the keyboard. Needs recent kdeui change
to work properly. svn path=/branches/work/kwin_composite/; revision=654259
This commit is contained in:
parent
67f830d223
commit
76cb5de294
10 changed files with 100 additions and 9 deletions
38
effects.cpp
38
effects.cpp
|
@ -32,7 +32,9 @@ namespace KWin
|
|||
{
|
||||
|
||||
|
||||
EffectsHandlerImpl::EffectsHandlerImpl(CompositingType type) : EffectsHandler(type)
|
||||
EffectsHandlerImpl::EffectsHandlerImpl(CompositingType type)
|
||||
: EffectsHandler(type)
|
||||
, keyboard_grab_effect( NULL )
|
||||
{
|
||||
foreach( const QString& effect, options->defaultEffects )
|
||||
loadEffect( effect );
|
||||
|
@ -40,11 +42,10 @@ EffectsHandlerImpl::EffectsHandlerImpl(CompositingType type) : EffectsHandler(ty
|
|||
|
||||
EffectsHandlerImpl::~EffectsHandlerImpl()
|
||||
{
|
||||
// Can't be done in EffectsHandler since it would result in pure virtuals
|
||||
// being called
|
||||
if( keyboard_grab_effect != NULL )
|
||||
ungrabKeyboard();
|
||||
foreach( EffectPair ep, loaded_effects )
|
||||
unloadEffect( ep.first );
|
||||
|
||||
foreach( InputWindowPair pos, input_windows )
|
||||
XDestroyWindow( display(), pos.second );
|
||||
}
|
||||
|
@ -237,6 +238,35 @@ void EffectsHandlerImpl::cursorMoved( const QPoint& pos, Qt::MouseButtons button
|
|||
ep.second->cursorMoved( pos, buttons );
|
||||
}
|
||||
|
||||
bool EffectsHandlerImpl::grabKeyboard( Effect* effect )
|
||||
{
|
||||
if( keyboard_grab_effect != NULL )
|
||||
return false;
|
||||
bool ret = grabXKeyboard();
|
||||
if( !ret )
|
||||
return false;
|
||||
keyboard_grab_effect = effect;
|
||||
return true;
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::ungrabKeyboard()
|
||||
{
|
||||
assert( keyboard_grab_effect != NULL );
|
||||
ungrabXKeyboard();
|
||||
keyboard_grab_effect = NULL;
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::grabbedKeyboardEvent( QKeyEvent* e )
|
||||
{
|
||||
if( keyboard_grab_effect != NULL )
|
||||
keyboard_grab_effect->grabbedKeyboardEvent( e );
|
||||
}
|
||||
|
||||
bool EffectsHandlerImpl::hasKeyboardGrab() const
|
||||
{
|
||||
return keyboard_grab_effect != NULL;
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::activateWindow( EffectWindow* c )
|
||||
{
|
||||
if( Client* cl = dynamic_cast< Client* >( static_cast<EffectWindowImpl*>(c)->window()))
|
||||
|
|
|
@ -43,6 +43,8 @@ class EffectsHandlerImpl : public EffectsHandler
|
|||
virtual int displayWidth() const;
|
||||
virtual int displayHeight() const;
|
||||
virtual QPoint cursorPos() const;
|
||||
virtual bool grabKeyboard( Effect* effect );
|
||||
virtual void ungrabKeyboard();
|
||||
virtual EffectWindowList stackingOrder() const;
|
||||
|
||||
virtual void setTabBoxWindow(EffectWindow*);
|
||||
|
@ -92,12 +94,15 @@ class EffectsHandlerImpl : public EffectsHandler
|
|||
void tabBoxUpdated();
|
||||
bool borderActivated( ElectricBorder border );
|
||||
void cursorMoved( const QPoint& pos, Qt::MouseButtons buttons );
|
||||
void grabbedKeyboardEvent( QKeyEvent* e );
|
||||
bool hasKeyboardGrab() const;
|
||||
|
||||
void loadEffect( const QString& name );
|
||||
void unloadEffect( const QString& name );
|
||||
|
||||
protected:
|
||||
KLibrary* findEffectLibrary( const QString& effectname );
|
||||
Effect* keyboard_grab_effect;
|
||||
};
|
||||
|
||||
class EffectWindowImpl : public EffectWindow
|
||||
|
|
|
@ -31,6 +31,7 @@ PresentWindowsEffect::PresentWindowsEffect()
|
|||
, mActivated( false )
|
||||
, mActiveness( 0.0 )
|
||||
, mRearranging( 1.0 )
|
||||
, hasKeyboardGrab( false )
|
||||
, mHoverWindow( NULL )
|
||||
{
|
||||
|
||||
|
@ -257,13 +258,16 @@ void PresentWindowsEffect::effectActivated()
|
|||
{
|
||||
// Create temporary input window to catch mouse events
|
||||
mInput = effects->createFullScreenInputWindow( this, Qt::PointingHandCursor );
|
||||
// TODO: maybe also create a KAction so that ressing Esc would terminate the effect?
|
||||
hasKeyboardGrab = effects->grabKeyboard( this );
|
||||
}
|
||||
|
||||
void PresentWindowsEffect::effectTerminated()
|
||||
{
|
||||
// Destroy the temporary input window
|
||||
effects->destroyInputWindow( mInput );
|
||||
if( hasKeyboardGrab )
|
||||
effects->ungrabKeyboard();
|
||||
hasKeyboardGrab = false;
|
||||
}
|
||||
|
||||
void PresentWindowsEffect::rearrangeWindows()
|
||||
|
@ -625,5 +629,14 @@ bool PresentWindowsEffect::borderActivated( ElectricBorder border )
|
|||
return false;
|
||||
}
|
||||
|
||||
void PresentWindowsEffect::grabbedKeyboardEvent( QKeyEvent* e )
|
||||
{
|
||||
if( e->key() == Qt::Key_Escape )
|
||||
{
|
||||
setActive( false );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
#include "presentwindows.moc"
|
||||
|
|
|
@ -38,6 +38,7 @@ class PresentWindowsEffect
|
|||
virtual void windowClosed( EffectWindow* c );
|
||||
virtual void windowInputMouseEvent( Window w, QEvent* e );
|
||||
virtual bool borderActivated( ElectricBorder border );
|
||||
virtual void grabbedKeyboardEvent( QKeyEvent* e );
|
||||
|
||||
public slots:
|
||||
void setActive(bool active);
|
||||
|
@ -76,6 +77,7 @@ class PresentWindowsEffect
|
|||
float mRearranging;
|
||||
|
||||
Window mInput;
|
||||
bool hasKeyboardGrab;
|
||||
|
||||
EffectWindowList mWindowsToPresent;
|
||||
struct WindowData
|
||||
|
|
17
events.cpp
17
events.cpp
|
@ -205,6 +205,9 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
mouse_emulation = false;
|
||||
ungrabXKeyboard();
|
||||
}
|
||||
if( effects && static_cast< EffectsHandlerImpl* >( effects )->hasKeyboardGrab()
|
||||
&& ( e->type == KeyPress || e->type == KeyRelease ))
|
||||
return false; // let Qt process it, it'll be intercepted again in eventFilter()
|
||||
|
||||
if ( e->type == PropertyNotify || e->type == ClientMessage )
|
||||
{
|
||||
|
@ -501,6 +504,20 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
return false;
|
||||
}
|
||||
|
||||
// Used only to filter events that need to be processed by Qt first
|
||||
// (e.g. keyboard input to be composed), otherwise events are
|
||||
// handle by the XEvent filter above
|
||||
bool Workspace::workspaceEvent( QEvent* e )
|
||||
{
|
||||
if(( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease || e->type() == QEvent::ShortcutOverride )
|
||||
&& effects && static_cast< EffectsHandlerImpl* >( effects )->hasKeyboardGrab())
|
||||
{
|
||||
static_cast< EffectsHandlerImpl* >( effects )->grabbedKeyboardEvent( static_cast< QKeyEvent* >( e ));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Some events don't have the actual window which caused the event
|
||||
// as e->xany.window (e.g. ConfigureRequest), but as some other
|
||||
// field in the XEvent structure.
|
||||
|
|
|
@ -86,6 +86,10 @@ void Effect::windowInputMouseEvent( Window, QEvent* )
|
|||
{
|
||||
}
|
||||
|
||||
void Effect::grabbedKeyboardEvent( QKeyEvent* )
|
||||
{
|
||||
}
|
||||
|
||||
void Effect::desktopChanged( int )
|
||||
{
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include <stdio.h>
|
||||
|
||||
class KLibrary;
|
||||
class QKeyEvent;
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -99,6 +100,7 @@ class KWIN_EXPORT Effect
|
|||
virtual void windowDamaged( EffectWindow* w, const QRect& r );
|
||||
virtual void windowGeometryShapeChanged( EffectWindow* w, const QRect& old );
|
||||
virtual void cursorMoved( const QPoint& pos, Qt::MouseButtons buttons );
|
||||
virtual void grabbedKeyboardEvent( QKeyEvent* e );
|
||||
|
||||
virtual void tabBoxAdded( int mode );
|
||||
virtual void tabBoxClosed();
|
||||
|
@ -172,6 +174,8 @@ class KWIN_EXPORT EffectsHandler
|
|||
virtual Window createFullScreenInputWindow( Effect* e, const QCursor& cursor );
|
||||
virtual void destroyInputWindow( Window w ) = 0;
|
||||
virtual QPoint cursorPos() const = 0;
|
||||
virtual bool grabKeyboard( Effect* effect ) = 0;
|
||||
virtual void ungrabKeyboard() = 0;
|
||||
|
||||
virtual void checkElectricBorder(const QPoint &pos, Time time) = 0;
|
||||
virtual void reserveElectricBorder( ElectricBorder border ) = 0;
|
||||
|
|
22
main.cpp
22
main.cpp
|
@ -14,7 +14,6 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
|
||||
#include "main.h"
|
||||
|
||||
#include <kglobal.h>
|
||||
#include <klocale.h>
|
||||
#include <stdlib.h>
|
||||
#include <kcmdlineargs.h>
|
||||
|
@ -26,11 +25,13 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include <stdio.h>
|
||||
#include <fixx11h.h>
|
||||
#include <QtDBus/QtDBus>
|
||||
#include <kglobal.h>
|
||||
|
||||
#include "atoms.h"
|
||||
#include "options.h"
|
||||
#include "sm.h"
|
||||
#include "utils.h"
|
||||
#include "effects.h"
|
||||
|
||||
#define INT8 _X11INT8
|
||||
#define INT32 _X11INT32
|
||||
|
@ -120,6 +121,8 @@ Application::Application( )
|
|||
options = new Options;
|
||||
atoms = new Atoms;
|
||||
|
||||
initting = false; // TODO
|
||||
|
||||
// create workspace.
|
||||
(void) new Workspace( isSessionRestored() );
|
||||
|
||||
|
@ -127,13 +130,15 @@ Application::Application( )
|
|||
|
||||
initting = false; // startup done, we are up and running now.
|
||||
|
||||
QDBusInterface ksplash( "org.kde.ksplash", "/ksplash", "org.kde.KSplash" );
|
||||
ksplash.call( "upAndRunning", QString( "wm started" ));
|
||||
XEvent e;
|
||||
e.xclient.type = ClientMessage;
|
||||
e.xclient.message_type = XInternAtom( display(), "_KDE_SPLASH_PROGRESS", False );
|
||||
e.xclient.display = display();
|
||||
e.xclient.window = rootWindow();
|
||||
e.xclient.format = 8;
|
||||
strcpy( e.xclient.data.b, "wm" );
|
||||
strcpy( e.xclient.data.b, "wm started" );
|
||||
XSendEvent( display(), rootWindow(), False, SubstructureNotifyMask, &e );
|
||||
}
|
||||
|
||||
|
@ -143,6 +148,8 @@ Application::~Application()
|
|||
if( owner.ownerWindow() != None ) // if there was no --replace (no new WM)
|
||||
XSetInputFocus( display(), PointerRoot, RevertToPointerRoot, xTime() );
|
||||
delete options;
|
||||
delete effects;
|
||||
delete atoms;
|
||||
}
|
||||
|
||||
void Application::lostSelection()
|
||||
|
@ -160,6 +167,13 @@ bool Application::x11EventFilter( XEvent *e )
|
|||
return KApplication::x11EventFilter( e );
|
||||
}
|
||||
|
||||
bool Application::notify( QObject* o, QEvent* e )
|
||||
{
|
||||
if( Workspace::self()->workspaceEvent( e ))
|
||||
return true;
|
||||
return KApplication::notify( o, e );
|
||||
}
|
||||
|
||||
static void sighandler(int)
|
||||
{
|
||||
QApplication::exit();
|
||||
|
@ -277,9 +291,9 @@ KDE_EXPORT int kdemain( int argc, char * argv[] )
|
|||
|
||||
QString appname;
|
||||
if (KWin::screen_number == 0)
|
||||
appname = "org.kde.kwin";
|
||||
appname = "kwin";
|
||||
else
|
||||
appname.sprintf("org.kde.kwin-screen-%d", KWin::screen_number);
|
||||
appname.sprintf("kwin-screen-%d", KWin::screen_number);
|
||||
|
||||
QDBusConnection::sessionBus().interface()->registerService( appname, QDBusConnectionInterface::DontQueueService );
|
||||
|
||||
|
|
1
main.h
1
main.h
|
@ -28,6 +28,7 @@ class Application : public KApplication
|
|||
|
||||
protected:
|
||||
bool x11EventFilter( XEvent * );
|
||||
bool notify( QObject* o, QEvent* e );
|
||||
private slots:
|
||||
void lostSelection();
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
static Workspace * self() { return _self; }
|
||||
|
||||
bool workspaceEvent( XEvent * );
|
||||
bool workspaceEvent( QEvent * );
|
||||
|
||||
KDecoration* createDecoration( KDecorationBridge* bridge );
|
||||
|
||||
|
|
Loading…
Reference in a new issue