[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    [Proposal + WIP (but working) patches]: Present Windows feature -
From:       Kelvie Wong <kelvie () ieee ! org>
Date:       2008-06-26 3:11:47
Message-ID: 200806252011.48047.kelvie () ieee ! org
[Download RAW message or body]

I sent this to the kwin mailing list, but I don't think many people subscribe to that, so I'll repost it here :)

----------  Forwarded Message  ----------

Subject: [Proposal + WIP (but working) patches]: Present Windows feature - move window to current desktop.
Date: Saturday, June 21, 2008
From: Kelvie Wong <kelvie@ieee.org>
To: kwin@kde.org

---
Attached is a couple of rough patches I've been using (on top of the KDE-svn) that enable me to do something 
that I do very often: move a window to the current desktop.  I no longer use a taskbar (with too many tasks 
across too many desktops, it becomes much harder to find the window I want without a fullscreen solution), so I 
managed to find some time to quickly read some of the API and hack this up.

Description
===========
What this patch does is that when the user holds down Alt and left click on a window (such is the default for 
moving the window with the mouse) inside Present Windows, the window will be moved to the current desktop (the 
effect is then disabled, and the user returns back to the desktop they were at), and the window will be attached 
to the mouse as if the user had used Alt+Left Click on a normal window.

This gives the user the illusion that the window is being dragged from the Present Windows effect into the 
current desktop.

The mouse position inside the window thumbnail is also taken into account (e.g. if you drag the window by its 
top left corner, the top left corner of the window will be attached to the mouse when it is un-thumbnailed).

Use Cases
=========
Again, this was done to scratch my own itch (and match my workflow), but here are some use cases:

1. The user is working on something, and sees that he received an instant message; kopete is in another desktop.  
He also has about 20 other windows open, scattered around his desktops.  He hits the shortcut key for Present 
Windows, and quickly finds kopete, uses Alt-click to quickly move kopete to the current desktop, and answers the 
message, and does not need to switch desktops to go back to work.

2. The user is quietly watching a streaming video, and notices that his CPU is doing something; rather than 
stopping the video, he can use Present Windows to find a terminal or KSysGuard quickly (either by looking or 
using the filter), and Alt-click to move the window to the current desktop with minimal interruption.

3. The user has 20-30 windows open (with multi-top level window applications like Gimp and Qt Designer, this 
isn't tough to do).  He wants to find a specific window to move to this desktop.  The task bar is a mess, and 
the windows stack over themselves too much in the Desktop Grid.  The quickest way to move a window to the 
current desktop would be Present Windows, as the user gets an overall view of _all_ windows, and also the 
ability to filter them.

API Additions
=============
This change required a new function in kwineffects to expose the mouseCommand functionality that is available 
(currently) only in the internal client libraries.

Improvements
============
As I've mentioned, this was a patch I quickly made to scratch my own 

1. The global KWin settings should be queried to find out the right key combination for "move window".

For me (and I would imagine, most other people), this is Alt+Left click, but this may change; it would probably 
be better to respect the user's choice in their "mouse move" shortcut.  This was beyond my knowledge w.r.t. how 
to implement this correctly (e.g., do I check the settings every time on a mouseEvent?  or should I store it 
during initialization?  if so, how do I change it?).

2. Maybe the windowMouseMove handler should be more generic to allow for more mouse commands later, such as a 
windowMouseCommand function that takes an enum telling it what to do.

3. Actions for Left, Right, Middle (and perhaps scroll wheel, as well) + modifiers should probably be 
customizable in the Present Windows settings box; and this could be one of the actions (To Current Desktop + 
mouse move).


Anyways, without further ado, the patches.

--
Kelvie Wong

---
 workspace/kwin/effects.cpp                |    7 +++++++
 workspace/kwin/effects.h                  |    1 +
 workspace/kwin/effects/presentwindows.cpp |   20 ++++++++++++++++++--
 workspace/kwin/lib/kwineffects.h          |    1 +
 4 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/workspace/kwin/effects.cpp b/workspace/kwin/effects.cpp
index 4db4c6f..8edd998 100644
--- a/workspace/kwin/effects.cpp
+++ b/workspace/kwin/effects.cpp
@@ -369,6 +369,13 @@ void EffectsHandlerImpl::windowToDesktop( EffectWindow* w, int desktop )
         Workspace::self()->sendClientToDesktop( cl, desktop, true );
     }
 
+void EffectsHandlerImpl::windowMouseMove( EffectWindow* w, const QPoint& pos )
+    {
+    Client* cl = dynamic_cast< Client* >( static_cast<EffectWindowImpl*>(w)->window());
+    if( cl && !cl->isDesktop() && !cl->isDock() && !cl->isTopMenu())
+        cl->performMouseCommand( Options::MouseMove, pos );
+    }
+
 int EffectsHandlerImpl::currentDesktop() const
     {
     return Workspace::self()->currentDesktop();
diff --git a/workspace/kwin/effects.h b/workspace/kwin/effects.h
index d14ee3e..d9cfaf7 100644
--- a/workspace/kwin/effects.h
+++ b/workspace/kwin/effects.h
@@ -53,6 +53,7 @@ class EffectsHandlerImpl : public EffectsHandler
         virtual EffectWindow* activeWindow() const;
         virtual void moveWindow( EffectWindow* w, const QPoint& pos );
         virtual void windowToDesktop( EffectWindow* w, int desktop );
+        virtual void windowMouseMove( EffectWindow* w, const QPoint& pos );
 
         virtual int currentDesktop() const;
         virtual int numberOfDesktops() const;
diff --git a/workspace/kwin/effects/presentwindows.cpp b/workspace/kwin/effects/presentwindows.cpp
index 6e9134e..aed0be0 100644
--- a/workspace/kwin/effects/presentwindows.cpp
+++ b/workspace/kwin/effects/presentwindows.cpp
@@ -265,13 +265,29 @@ void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent* e )
         }
 
     // Find out which window (if any) was clicked and activate it
-    QPoint pos = static_cast< QMouseEvent* >( e )->pos();
+    QMouseEvent *me = static_cast< QMouseEvent* >( e );
+    QPoint pos = me->pos();
     for( DataHash::iterator it = mWindowData.begin();
          it != mWindowData.end(); ++it )
         {
         if( it.value().area.contains(pos) )
+        {
+            if( me->modifiers() & Qt::AltModifier )
             {
-            effects->activateWindow( it.key() );
+                EffectWindow *ew = it.key();
+                QRectF areaF(it.value().area);
+                QPointF posF(pos);
+                posF -= areaF.topLeft();
+                qreal x_ratio = posF.x() / areaF.width();
+                qreal y_ratio = posF.y() / areaF.height();
+
+                QPointF newPos(pos);
+                newPos -= QPointF( x_ratio * ew->width(), y_ratio * ew->height() );
+                effects->windowToDesktop( it.key(), effects->currentDesktop() );
+                effects->moveWindow( ew, newPos.toPoint() );
+                effects->windowMouseMove( ew, cursorPos() );
+            }
+                effects->activateWindow( it.key() );
             // mWindowData gets cleared and rebuilt when a window is
             // activated, so it's dangerous (and unnecessary) to continue
             break;
diff --git a/workspace/kwin/lib/kwineffects.h b/workspace/kwin/lib/kwineffects.h
index 32397b7..b86b2a0 100644
--- a/workspace/kwin/lib/kwineffects.h
+++ b/workspace/kwin/lib/kwineffects.h
@@ -470,6 +470,7 @@ class KWIN_EXPORT EffectsHandler
         virtual EffectWindow* activeWindow() const = 0 ;
         virtual void moveWindow( EffectWindow* w, const QPoint& pos ) = 0;
         virtual void windowToDesktop( EffectWindow* w, int desktop ) = 0;
+        virtual void windowMouseMove( EffectWindow* w, const QPoint& pos) = 0;
         // 
         virtual int currentDesktop() const = 0;
         virtual int numberOfDesktops() const = 0;
-- 
1.5.6.GIT


-------------------------------------------------------
-- 
Kelvie Wong
 
>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic