Bug 124807

Summary: Alt Tab not working as expected
Product: [Plasma] kwin Reporter: Rohan Dhruva <rohandhruva>
Component: generalAssignee: KWin default assignee <kwin-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: ana, opensource, pfeiffer
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Unlisted Binaries   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: Focus policy settings
Focus stealing prevention settings

Description Rohan Dhruva 2006-04-03 08:15:48 UTC
Version:            (using KDE KDE 3.5.2)
Installed from:    Unspecified Linux
Compiler:          gcc (GCC) 4.0.3
 Also tested on a system with gcc 4.1
OS:                Linux

I am using arch linux, and frugalware linux. I am using kde 3.5.2 from their own packages.
Scenario 1: 
I have konsole, konqueror and firefox open. I minimize firefox, and continue working in konsole, with konqueror maximized. I press alt-tab.. 
Expected Behaviour : Activate konqueror, since firefox is minimized. That was what happened in kde 3.4.x - 3.5.1. 
What happens in kde 3.5.2 is that firefox opens ... This happens on both arch and frugalware

Scenario 2:
I have konsole, and konqueror open on www.foo.org. konsole is the active window, and I am working in it. I click on system menu, and "Home Folder". The new konqueror window opens, with ~. The window is not activated by default, but flashes the 'urgent' hint, the flashing of the window in taskbar. I press alt-tab
Expected : Activate the new konqueror with ~, since that is flashing the window manager 'urgent' hint. That was what happened with kde 3.4.x to 3.5.1.
In kde 3.5.2, the konqueror with www.foo.org opens, since that was the window I was originally alt-tabbing with.

What I have said here for 2-3 windows applies even when 10 windows are open, I tried. I tried creating a new fresh user after the kde 3.5.2 upgrade, the problem still exists. I hope it is not a new 'feature', in which case I will file a wishlist to revert it back to the original behaviour ;)

Thanks, 
Rohan.
Comment 1 illogic-al 2006-04-03 21:40:39 UTC
I can confirm that scenario 1 does happen with 3.5.1.
I cannot however confirm that scenario 2 happens in 3.5.1. This probably has something to do with how your Focus Policy is set up so I need more information on how you've configured that. 
I'll hold off on the kde 3.5.2 update (to confirm the actual report) until I get this information.
Comment 2 Rohan Dhruva 2006-04-03 21:54:45 UTC
I am sure that the scenario1 bug was not present in kde 3.5.1. I might be wrong, but I remember having the behaviour on kde 3.5.1. Since that is what I have used for comparison. Anyway, someone on kde 3.5.1 please confirm.

I am attaching a screen shot of my focus settings, mostly default. And as I said, the problem exists on new freshly created user too.
Comment 3 Rohan Dhruva 2006-04-03 21:56:26 UTC
Created attachment 15447 [details]
Focus policy settings

Please tell if any more info is needed.
Comment 4 illogic-al 2006-04-03 22:00:47 UTC
ok, there seems to be some confusion caused by my comments. I'll attempt to clarify.
I can confirm that the _Expected Behavior_ listed in Scenario 1, does in fact occur for 3.5.1. 
I can NOT confirm that the _Expected Behavior_ listed in Scenario 2, occurs for 3.5.1.
Comment 5 Rohan Dhruva 2006-04-03 22:09:19 UTC
Created attachment 15448 [details]
Focus stealing prevention settings

As requested by illogical. Note : the problem is prevalent even when the level
is set from "Low" to "Normal". I have not tried higher levels.
Comment 6 illogic-al 2006-04-03 22:16:22 UTC
OK, I can now confirm the Expected Behavior for Scenario 2, when KDE 3.5.1's focus stealing prevention level is set to "High". If set to anything lower in 3.5.1 the new ~ konq window gains focus in which case an ALT+TAB will just switch *away* from it).
Comment 7 Rohan Dhruva 2006-04-03 22:27:32 UTC
Yes, in simple words, the point is - 
1) Minimized windows must be in the absolute bottom when the alt-tab window list is shown, so as not to navigate to it and

2) Urgent requesting windows must be in the absolute top, so that the next time I press alt-tab that window must get activated.
Comment 8 illogic-al 2006-04-04 00:05:53 UTC
I've confirmed this on 3.5.2. So this change in behavior was introduced between 3.5.1 and 3.5.2.
It also applies to KDE windows (not firefx specific) 
Comment 9 Rohan Dhruva 2006-04-04 06:03:56 UTC
Yes, it is not firefox specific. Its just that I use that type of scenario mentioned above, frequently. Also, if this is meant as a new "feature" of kde 3.5.2, please change this to a "wishlist" request to revert the change.
Comment 10 Rohan Dhruva 2006-04-05 10:02:41 UTC
I am told that this problem does not occur on debian. I am looking at -- http://ftp.debian.org/debian/pool/main/k/kdebase/kdebase_3.5.2-1.diff.gz -- but I cant find any patch that fixes the kwin problem, can someone please look ? I will try some more hunting, in any case :)
Comment 11 Jaison Lee 2006-04-07 16:03:24 UTC
*** Bug 125093 has been marked as a duplicate of this bug. ***
Comment 12 Lubos Lunak 2006-04-11 17:07:57 UTC
SVN commit 528629 by lunakl:

Move minimized windows to the right place in focus chain.
BUG: 124807



 M  +1 -1      activation.cpp  
 M  +4 -3      client.cpp  
 M  +1 -1      events.cpp  
 M  +21 -7     workspace.cpp  
 M  +2 -1      workspace.h  


--- branches/KDE/3.5/kdebase/kwin/activation.cpp #528628:528629
@@ -231,7 +231,7 @@
         last_active_client = active_client;
     if ( active_client ) 
         {
-        updateFocusChains( active_client, true ); // make it first in focus chain
+        updateFocusChains( active_client, FocusChainMakeFirst );
         active_client->demandAttention( false );
         }
     pending_take_activity = NULL;
--- branches/KDE/3.5/kdebase/kwin/client.cpp #528628:528629
@@ -578,7 +578,7 @@
     updateAllowedActions();
     workspace()->updateMinimizedOfTransients( this );
     updateWindowRules();
-    workspace()->updateFocusChains( this, false ); // make it last in the focus chain
+    workspace()->updateFocusChains( this, Workspace::FocusChainMakeLast );
     }
 
 void Client::unminimize( bool avoid_animation )
@@ -1158,7 +1158,8 @@
     info->setState( b?NET::SkipTaskbar:0, NET::SkipTaskbar );
     updateWindowRules();
     if( was_wants_tab_focus != wantsTabFocus())
-        workspace()->updateFocusChains( this, isActive());
+        workspace()->updateFocusChains( this,
+            isActive() ? Workspace::FocusChainMakeFirst : Workspace::FocusChainUpdate );
     }
 
 void Client::setSkipPager( bool b )
@@ -1200,7 +1201,7 @@
         }
     if( decoration != NULL )
         decoration->desktopChange();
-    workspace()->updateFocusChains( this, true );
+    workspace()->updateFocusChains( this, Workspace::FocusChainMakeFirst );
     updateVisibility();
     updateWindowRules();
     }
--- branches/KDE/3.5/kdebase/kwin/events.cpp #528628:528629
@@ -370,7 +370,7 @@
             if( c )
                 {
                 c->windowEvent( e );
-                updateFocusChains( c, true );
+                updateFocusChains( c, FocusChainUpdate );
                 return true;
                 }
             break;
--- branches/KDE/3.5/kdebase/kwin/workspace.cpp #528628:528629
@@ -512,7 +512,7 @@
         }
     else
         {
-        updateFocusChains( c, false ); // add to focus chain if not already there
+        updateFocusChains( c, FocusChainUpdate ); // add to focus chain if not already there
         clients.append( c );
         }
     if( !unconstrained_stacking_order.contains( c ))
@@ -591,7 +591,7 @@
     updateClientArea();
     }
 
-void Workspace::updateFocusChains( Client* c, bool make_first )
+void Workspace::updateFocusChains( Client* c, FocusChainChange change )
     {
     if( !c->wantsTabFocus()) // doesn't want tab focus, remove
         {
@@ -605,11 +605,15 @@
     if(c->desktop() == NET::OnAllDesktops)
         { //now on all desktops, add it to focus_chains it is not already in
         for( int i=1; i<= numberOfDesktops(); i++)
-            { // make_first works only on current desktop, don't affect all desktops
-            if( make_first && i == currentDesktop())
+            { // making first/last works only on current desktop, don't affect all desktops
+            if( i == currentDesktop()
+                && ( change == FocusChainMakeFirst || change == FocusChainMakeLast ))
                 {
                 focus_chain[ i ].remove( c );
-                focus_chain[ i ].append( c );
+                if( change == FocusChainMakeFirst )
+                    focus_chain[ i ].append( c );
+                else
+                    focus_chain[ i ].prepend( c );
                 }
             else if( !focus_chain[ i ].contains( c ))
                 focus_chain[ i ].prepend( c ); // otherwise add as the last one
@@ -621,11 +625,16 @@
             {
             if( i == c->desktop())
                 {
-                if( make_first )
+                if( change == FocusChainMakeFirst )
                     {
                     focus_chain[ i ].remove( c );
                     focus_chain[ i ].append( c );
                     }
+                else if( change == FocusChainMakeLast )
+                    {
+                    focus_chain[ i ].remove( c );
+                    focus_chain[ i ].prepend( c );
+                    }
                 else if( !focus_chain[ i ].contains( c ))
                     focus_chain[ i ].prepend( c );
                 }
@@ -633,11 +642,16 @@
                 focus_chain[ i ].remove( c );
             }
         }
-    if( make_first )
+    if( change == FocusChainMakeFirst )
         {
         global_focus_chain.remove( c );
         global_focus_chain.append( c );
         }
+    else if( change == FocusChainMakeLast )
+        {
+        global_focus_chain.remove( c );
+        global_focus_chain.prepend( c );
+        }
     else if( !global_focus_chain.contains( c ))
         global_focus_chain.prepend( c );
     }
--- branches/KDE/3.5/kdebase/kwin/workspace.h #528628:528629
@@ -251,7 +251,8 @@
         bool checkStartupNotification( Window w, KStartupInfoId& id, KStartupInfoData& data );
 
         void focusToNull(); // SELI public?
-        void updateFocusChains( Client* c, bool make_first );
+        enum FocusChainChange { FocusChainMakeFirst, FocusChainMakeLast, FocusChainUpdate };
+        void updateFocusChains( Client* c, FocusChainChange change );
         
         bool forcedGlobalMouseGrab() const;
         void clientShortcutUpdated( Client* c );
Comment 13 Rohan Dhruva 2006-04-11 19:09:41 UTC
Thanks for fixing it so fast ! :)
Comment 14 Lubos Lunak 2006-04-18 13:04:25 UTC
*** Bug 125797 has been marked as a duplicate of this bug. ***
Comment 15 Rohan Dhruva 2006-04-27 11:44:14 UTC
Just for the record, I have filed a wishlist on debian as well as ubuntu to request merge of this patch in kdebase. Links:

http://bugs.debian.org/363357
https://launchpad.net/bugs/40089

Also, talked to the frugalware developer, he will most probably be rebuilding the kdebase package, incorporating this patch.