Subject: FVWM: Alt-tab

From: Stian Sletner <[email-masked]>
Date: Sat, 20 Apr 2002 14:59:10 +0200

Ah yes, the infamous alt-tab.  I for one cannot live without it working
correctly, and I was very happy to see that FVWM had made an attempt at
implementing it.  However, I'm not satisfied, as they seem to have
complicated it unecessarily. :)  What I expect from alt-tab is to get a
window list on my screen (this works), which is sorted in
last-active-order (I think this works, too), wherein the second window
is selected (this does not work, the first window (the one I'm already
in) is selected, and instead there's a timeout for quick switches).  So
for quick alt-tabbing between two windows, FVWM's implementation works,
but for getting to a third window in the list (alt-tab-tab, release) (or
any other window), it doesn't work at all like expected, instead it
brings me to the second window on the second press of tab, unless I wait
a while, for some reason.

So I guess my question is, can I make it behave more closely in
accordance with that other GUI?

-- 
Stian Sletner
--
Visit the official FVWM web page at <URL: http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm" in the body of a
message to [email-masked].
To report problems, send mail to [email-masked].

---

From: Mikhael Goikhman <[email-masked]>
Date: Sat, 20 Apr 2002 15:19:17 +0000

> accordance with that other GUI?

No, you can't currently. Menus invoked by a keyboard select the first
item, not the second. Maybe in the future, but not now.

Regards,
Mikhael.

---

From: Jochen Klenner <[email-masked]>
Date: Tue, 23 Apr 2002 00:48:15 +0200 (MEST)

> accordance with that other GUI?

Unfortunately you didn't state what version of Fvwm you are using. The
attached patch is against the current snapshot (fvwm-snap-20020422), but
it may also work on other versions -- it's practically the same patch
since version 2.4.6. Just try it.

It adds the new option "currentAtEnd" to the windowlist command. Usage:

Key     Tab     A       M       WindowList CurrentAtEnd

As the name suggests, this moves the currently focused window to the end
of the windowlist.
When you now hit alt-tab once, the last focused window is selected, when
you hit it twice the second last focused one, and so on. In conjunction
with SelectOnRelease it works just like "that other GUI". The current
window at the end of the list might look a bit funny, but, hey, when you
bring up the windowlist, the current window is probably the least
interesting one at the moment.

Frankly, I do not understand the stuff about the timeout. It doesn't seem
to work according to the description you gave, at least in this snapshot.
Anyway, with my patch applied, there aren't any timeouts in the
windowlist, it simply works like you requested it.

I hope, this is helpful for you.

Best regards

Jochen
--- ../fvwm-snap-20020422/fvwm/windowlist.c	Mon Mar 18 13:30:03 2002
+++ fvwm/windowlist.c	Mon Apr 22 23:31:46 2002
@@ -153,6 +153,7 @@
   /* Condition vars. */
   Bool use_condition = False;
   Bool do_reverse_sort_order = False;
+  Bool current_at_end = False;
   WindowConditionMask mask;
   char *cond_flags;
   Bool first_desk = True;
@@ -219,6 +220,8 @@
         flags |= SHOW_ALPHABETIC;
       else if (StrEquals(tok,"ReverseOrder"))
         do_reverse_sort_order = True;
+      else if (StrEquals(tok,"CurrentAtEnd"))
+	current_at_end = True;
       else if (StrEquals(tok,"NoDeskSort"))
         flags |= NO_DESK_SORT;
       else if (StrEquals(tok,"UseIconName"))
@@ -360,8 +363,15 @@
     return;
   }
   /* get the windowlist starting from the current window (if any)*/
-  if ((t = get_focus_window()) == NULL)
+  t = get_focus_window();
+  if (t == NULL)
     t = Scr.FvwmRoot.next;
+  else if (current_at_end) {
+    if (t->next)
+      t = t->next;
+    else
+      t = Scr.FvwmRoot.next;
+  }
   for (ii = 0; ii < numWindows; ii++)
   {
     if (do_reverse_sort_order)
--- ../fvwm-snap-20020422/ChangeLog	Tue Apr 23 00:24:40 2002
+++ ChangeLog	Tue Apr 23 00:31:23 2002
@@ -1,3 +1,8 @@
+2002-04-23  Jochen Klenner  <[email-masked]>
+
+	* fvwm/windowlist.c (CMD_WindowList):
+	Added new Windowlist option CurrentAtEnd
+
 2002-04-22  olicha  <[email-masked]>
 
 	* fvwm/Makefile.am:

---

From: Stian Sletner <[email-masked]>
Date: Tue, 23 Apr 2002 01:13:26 +0200

* At 2002-04-23T00:48+0200, Jochen Klenner wrote:
: 
| Unfortunately you didn't state what version of Fvwm you are using. The
| attached patch is against the current snapshot (fvwm-snap-20020422), but
| it may also work on other versions -- it's practically the same patch
| since version 2.4.6. Just try it.

Sorry about that.  I'm using 2.4.6, and the patch applied out of the box
(apart from the non-cruical ChangeLog part).

| It adds the new option "currentAtEnd" to the windowlist command. Usage:
| 
| Key     Tab     A       M       WindowList CurrentAtEnd
| 
| As the name suggests, this moves the currently focused window to the end
| of the windowlist.
| When you now hit alt-tab once, the last focused window is selected, when
| you hit it twice the second last focused one, and so on. In conjunction
| with SelectOnRelease it works just like "that other GUI". The current
| window at the end of the list might look a bit funny, but, hey, when you
| bring up the windowlist, the current window is probably the least
| interesting one at the moment.

It isn't a bit funny.  It is exactly like the other GUI does it.  And we
all know there's nothing funny about that.  However, this is also
exactly how I want it, and I think it's perfectly logical that this is
the way it should be, for the very reason you stated.

| Frankly, I do not understand the stuff about the timeout. It doesn't seem
| to work according to the description you gave, at least in this snapshot.

I was using the example bindings from fvwm95, I guess that's what did
it.

| Anyway, with my patch applied, there aren't any timeouts in the
| windowlist, it simply works like you requested it.
| 
| I hope, this is helpful for you.

It most certainly is.  This makes me a very happy man.  Thank you so
much.  In some distant future when I've got more than $0.000, I will buy
you a beer. :)

Now, if I could only stop it from warping my mouse pointer, things would
_really_ be starting to look good...

---

From: Mikhael Goikhman <[email-masked]>
Date: Mon, 22 Apr 2002 23:33:40 +0000

> As the name suggests, this moves the currently focused window to the end

Ok, I will apply your patch to both branches.
But next time please patch the man page too.

> interesting one at the moment.

I don't know... For me the current window is the most interesting one. :)
I don't want to be switched to another window just because I want to
see a list of all windows. :)

I am not against to make CurrentAtEnd the default for Alt-Tab, but I will
not do this myself. Because I think the current way with a correct order
is better than with CurrentAtEnd.

> to work according to the description you gave, at least in this snapshot.

This timeout feature works like this. The sample from the man page:

  AddToFunc SwitchToWindow I WindowListFunc $w
  Key Tab A M WindowList "Prev SwitchToWindow"

When you press Alt-Tab and quickly press Tab again or when you quickly
release both keys, the "Prev SwitchToWindow" is executed.
  
> I hope, this is helpful for you.

Yes, I think it will help people that want one-press-to-another-window
behaviour, thanks.

Regards,
Mikhael.

---

From: Stian Sletner <[email-masked]>
Date: Tue, 23 Apr 2002 06:41:51 +0200

* At 2002-04-23T01:13+0200, Stian Sletner wrote:
: 
| Now, if I could only stop it from warping my mouse pointer, things would
| _really_ be starting to look good...

(Wohoo, figured that part out for myself.)

---

From: Stian Sletner <[email-masked]>
Date: Fri, 26 Apr 2002 06:20:08 +0200

Using this now, and it's working great.  I was sitting here fiddling
around with my settings, and it suddenly occured to me that I would like
this option to the Iconify command as well.  Or, I cannot say how the
optimal implementation in FVWM would be, maybe it's even doable just
with config (though I couldn't figure out how), but I would like
iconified (minimized) windows to be moved to the bottom of the
WindowList, so that a quick alt-tab after minimizing a window does not
bring it right back up.  Again, this will be mimicing "that other GUI".

Can this be done, somehow? :)

Also, another (more simple) question.  Can I make the WindowList local
to the "page"?  It looks to me like I can't, but perhaps local to the
"desk" (in which case I could make alot of desks, and only have one page
per desk, to mimic what I want?)  And if so, how can I make sure that
the last active window in a page gets selected as I change to it (the
page)?

Please excuse me if I'm being incoherent, it's 6am and I haven't slept
yet.

---

From: Mikhael Goikhman <[email-masked]>
Date: Fri, 26 Apr 2002 20:31:03 +0000

> Can this be done, somehow? :)

What you want is for the Iconify command to move the window to the tail of
the window list (from the head). This is probably doable now using some
tricky script, but I don't think it is easy.

The problem is that the Iconify command already transferes the focus, i.e.
changes this list, but not in the way you want. A solution may be to add
a global or Style option, like IconifyBringsToEnd or similar.

Another solution is to add IconifiedAtEnd option to WindowList.

Maybe someone else can suggest other solutions that don't require changes
to the code.

> the last active window in a page gets selected as I change to it (the

WindowList only works with desks now. This is probably due to the fact
that (non-sticky) windows may occupy several pages, but only one desk.
But there is nothing that prevents adding CurrentPage option to WindowList.

If you want more "that other GUI" feel, don't use pages, use desktops of
one page only (DesktopSize 1x1) and then use "WindowList CurrentDesk".

Regards,
Mikhael.

---

From: Stian Sletner <[email-masked]>
Date: Sat, 27 Apr 2002 00:39:52 +0200

* At 2002-04-26T20:31+0000, Mikhael Goikhman wrote:
:
| WindowList only works with desks now. This is probably due to the fact
| that (non-sticky) windows may occupy several pages, but only one desk.
| But there is nothing that prevents adding CurrentPage option to WindowList.
| 
| If you want more "that other GUI" feel, don't use pages, use desktops of
| one page only (DesktopSize 1x1) and then use "WindowList CurrentDesk".

Yep, this did the trick.  I can live without the pager.  Thanks.

---

From: Mikhael Goikhman <[email-masked]>
Date: Fri, 26 Apr 2002 23:23:39 +0000

> Yep, this did the trick.  I can live without the pager.  Thanks.

Ok, if you ever need a pager showing desks, run it as "FvwmPager 0 3".
In case you don't know it already.

Regards,
Mikhael.

---

From: Stian Sletner <[email-masked]>
Date: Sat, 27 Apr 2002 02:13:45 +0200

* At 2002-04-26T23:23+0000, Mikhael Goikhman wrote:
: 
| Ok, if you ever need a pager showing desks, run it as "FvwmPager 0 3".
| In case you don't know it already.

Ahem.  Indeed. :D  Thanks.

---

From: Stian Sletner <[email-masked]>
Date: Mon, 29 Apr 2002 21:10:52 +0200

* At 2002-04-26T20:31+0000, Mikhael Goikhman wrote:
: 
| What you want is for the Iconify command to move the window to the tail of
| the window list (from the head). This is probably doable now using some
| tricky script, but I don't think it is easy.
| 
| The problem is that the Iconify command already transferes the focus, i.e.
| changes this list, but not in the way you want. A solution may be to add
| a global or Style option, like IconifyBringsToEnd or similar.
| 
| Another solution is to add IconifiedAtEnd option to WindowList.

I hacked this last solution into the code, now.  I've included a patch
for it, since I would really like to see this feature in FVWM.  However,
since I'm new to both using and hacking FVWM, my patch should probably
be thoroughly checked before applied to anything (though it seems to
work).  This patch is against 2.4.6, and thus includes the CurrentAtEnd
patch Jochen Klenner made (I had to make a little addition to it, too,
so that the current window comes behind the iconified ones).

(IconifiedAtEnd patch: diff -c fvwm/windowlist.c.orig fvwm/windowlist.c)

*** fvwm/windowlist.c.orig	Fri Feb 22 23:07:48 2002
--- fvwm/windowlist.c	Mon Apr 29 21:03:09 2002
***************
*** 87,92 ****
--- 87,93 ----
    char* ret_action = NULL;
    FvwmWindow *t;
    FvwmWindow **windowList;
+   FvwmWindow **iconifiedList;
    int numWindows;
    int ii;
    char tname[80] = "";
***************
*** 121,126 ****
--- 122,131 ----
    /* Condition vars. */
    Bool use_condition = False;
    Bool do_reverse_sort_order = False;
+   Bool current_at_end = False;
+   Bool iconified_at_end = False;
+   int ic = 0;
+   int ij;
    WindowConditionMask mask;
    char *cond_flags;
  
***************
*** 183,188 ****
--- 188,197 ----
          flags |= SHOW_ALPHABETIC;
        else if (StrEquals(tok,"ReverseOrder"))
          do_reverse_sort_order = True;
+       else if (StrEquals(tok,"CurrentAtEnd"))
+ 	current_at_end = True;
+       else if (StrEquals(tok,"IconifiedAtEnd"))
+ 	iconified_at_end = True;
        else if (StrEquals(tok,"NoDeskSort"))
          flags |= NO_DESK_SORT;
        else if (StrEquals(tok,"UseIconName"))
***************
*** 312,331 ****
    {
      return;
    }
    /* get the windowlist starting from the current window (if any)*/
!   if ((t = get_focus_window()) == NULL)
      t = Scr.FvwmRoot.next;
    for (ii = 0; ii < numWindows; ii++)
    {
      if (do_reverse_sort_order)
        windowList[numWindows - ii - 1] = t;
      else
!       windowList[ii] = t;
      if (t->next)
        t = t->next;
      else
        t = Scr.FvwmRoot.next;
    }
  
    /* Do alphabetic sort */
    if (flags & SHOW_ALPHABETIC)
--- 321,364 ----
    {
      return;
    }
+   if (iconified_at_end)
+   {
+     iconifiedList = malloc(numWindows*sizeof(t));
+     if (iconifiedList == NULL)
+       return;
+   }
    /* get the windowlist starting from the current window (if any)*/
!   t = get_focus_window();
!   if (t == NULL)
      t = Scr.FvwmRoot.next;
+   else if (current_at_end) {
+     if (t->next)
+       t = t->next;
+     else
+       t = Scr.FvwmRoot.next;
+   }
    for (ii = 0; ii < numWindows; ii++)
    {
      if (do_reverse_sort_order)
        windowList[numWindows - ii - 1] = t;
+     else if (iconified_at_end && IS_ICONIFIED(t))
+       iconifiedList[ic++] = t;
      else
!       windowList[ii - ic] = t;
      if (t->next)
        t = t->next;
      else
        t = Scr.FvwmRoot.next;
    }
+   if (iconified_at_end && ic > 0)
+   {
+     if (current_at_end)
+       windowList[numWindows - 1] = windowList[--ii - ic];
+     for (ij = 0; ij < ic; ij++)
+     {
+       windowList[ij + (ii - ic)] = iconifiedList[ij];
+     }
+   }
  
    /* Do alphabetic sort */
    if (flags & SHOW_ALPHABETIC)
***************
*** 511,516 ****
--- 544,551 ----
    if (func)
      free(func);
    free(windowList);
+   if (iconified_at_end)
+     free(iconifiedList);
    if (!default_action && eventp && eventp->type == KeyPress)
      teventp = (XEvent *)1;
    else

---

From: Mikhael Goikhman <[email-masked]>
Date: Mon, 29 Apr 2002 19:32:17 +0000

> (IconifiedAtEnd patch: diff -c fvwm/windowlist.c.orig fvwm/windowlist.c)

Several points.

Patches should be done using "diff -u" unless your diff only supports -c.
Patches should be done againt the latest version (one of the latest daily
snapshot is ok).
Patches should include changes to fvwm.1 and a ChangeLog entry.

Please save us the time. Otherwise whoever applies your patch should spend
time to understand a hard-to-read "diff -c" output, manually port the
patch from 2.4.x to 2.5.x, manually separate already applied CurrentAtEnd
patch from yours, write a man page entry. At this point it is easier to
implement the feature from stratch. :)  Thank you and happy patching.

Regards,
Mikhael.

---

From: Stian Sletner <[email-masked]>
Date: Mon, 29 Apr 2002 21:41:16 +0200

* At 2002-04-29T19:32+0000, Mikhael Goikhman wrote:
: 
| Patches should be done using "diff -u" unless your diff only supports -c.
| Patches should be done againt the latest version (one of the latest daily
| snapshot is ok).
| Patches should include changes to fvwm.1 and a ChangeLog entry.
| 
| Please save us the time. Otherwise whoever applies your patch should spend
| time to understand a hard-to-read "diff -c" output, manually port the
| patch from 2.4.x to 2.5.x, manually separate already applied CurrentAtEnd
| patch from yours, write a man page entry. At this point it is easier to
| implement the feature from stratch. :)  Thank you and happy patching.

That should probably be done anyway.  Nevermind, thanks.

---

From: Stian Sletner <[email-masked]>
Date: Mon, 29 Apr 2002 23:22:45 +0200

* At 2002-04-29T21:41+0200, Stian Sletner wrote:
| * At 2002-04-29T19:32+0000, Mikhael Goikhman wrote:
| : 
| | Patches should be done using "diff -u" unless your diff only supports -c.
| | Patches should be done againt the latest version (one of the latest daily
| | snapshot is ok).
| | Patches should include changes to fvwm.1 and a ChangeLog entry.
| | 
| | Please save us the time. Otherwise whoever applies your patch should spend
| | time to understand a hard-to-read "diff -c" output, manually port the
| | patch from 2.4.x to 2.5.x, manually separate already applied CurrentAtEnd
| | patch from yours, write a man page entry. At this point it is easier to
| | implement the feature from stratch. :)  Thank you and happy patching.
| 
| That should probably be done anyway.  Nevermind, thanks.

On second thought, I have nothing better to do.  I'll tro and do it
again, following your instructions.

---

From: Stian Sletner <[email-masked]>
Date: Tue, 30 Apr 2002 00:05:00 +0200

* At 2002-04-29T23:22+0200, Stian Sletner wrote:
| * At 2002-04-29T21:41+0200, Stian Sletner wrote:
| | * At 2002-04-29T19:32+0000, Mikhael Goikhman wrote:
| | : 
| | | Patches should be done using "diff -u" unless your diff only supports -c.
| | | Patches should be done againt the latest version (one of the latest daily
| | | snapshot is ok).
| | | Patches should include changes to fvwm.1 and a ChangeLog entry.
| | | 
| | | Please save us the time. Otherwise whoever applies your patch should spend
| | | time to understand a hard-to-read "diff -c" output, manually port the
| | | patch from 2.4.x to 2.5.x, manually separate already applied CurrentAtEnd
| | | patch from yours, write a man page entry. At this point it is easier to
| | | implement the feature from stratch. :)  Thank you and happy patching.
| | 
| | That should probably be done anyway.  Nevermind, thanks.
| 
| On second thought, I have nothing better to do.  I'll tro and do it
| again, following your instructions.

Ok, how's this?  Patched against cvs current, default branch.

Index: ChangeLog
===================================================================
RCS file: /home/cvs/fvwm/fvwm/ChangeLog,v
retrieving revision 1.1772
diff -u -u -r1.1772 ChangeLog
--- ChangeLog	2002/04/29 15:52:49	1.1772
+++ ChangeLog	2002/04/29 22:00:20
@@ -1,3 +1,8 @@
+2002-04-29  Stian Sletner  <[email-masked]>
+
+	* fvwm/windowlist.c (CMD_WindowList):
+	Added new Windowlist option IconifiedAtEnd
+
 2002-04-29  olicha  <[email-masked]>
 
 	* libs/FlocaleCharset.c (FlocaleCharsetSetFlocaleCharset):
Index: fvwm/fvwm.1
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/fvwm.1,v
retrieving revision 1.6
diff -u -u -r1.6 fvwm.1
--- fvwm/fvwm.1	2002/04/25 21:57:02	1.6
+++ fvwm/fvwm.1	2002/04/29 22:01:38
@@ -3704,6 +3704,7 @@
 .IR NoDeskSort ,
 .IR ReverseOrder ,
 .IR CurrentAtEnd ,
+.IR IconifiedAtEnd ,
 .IR UseIconName ,
 .IR Alphabetic " / " NotAlphabetic ,
 .IR NoHotkeys ,
@@ -3742,6 +3743,10 @@
 option the currently focused window (if any) is shown at the bottom
 of the list.  This is mostly intended for simulating the Alt-Tab
 behaviour in another GUI.
+
+.I IconifiedAtEnd
+makes iconified windows be moved to the end of the list.  This is also
+from another GUI.
 
 The
 .I NoGeometry
Index: fvwm/windowlist.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/windowlist.c,v
retrieving revision 1.58
diff -u -u -r1.58 windowlist.c
--- fvwm/windowlist.c	2002/04/23 01:26:53	1.58
+++ fvwm/windowlist.c	2002/04/29 22:01:46
@@ -119,6 +119,7 @@
   char* ret_action = NULL;
   FvwmWindow *t;
   FvwmWindow **windowList;
+  FvwmWindow **iconifiedList;
   int numWindows;
   int ii;
   char tname[80];
@@ -154,6 +155,9 @@
   Bool use_condition = False;
   Bool do_reverse_sort_order = False;
   Bool current_at_end = False;
+  Bool iconified_at_end = False;
+  int ic = 0;
+  int ij;
   WindowConditionMask mask;
   char *cond_flags;
   Bool first_desk = True;
@@ -222,6 +226,8 @@
         do_reverse_sort_order = True;
       else if (StrEquals(tok,"CurrentAtEnd"))
         current_at_end = True;
+      else if (StrEquals(tok,"IconifiedAtEnd"))
+        iconified_at_end = True;
       else if (StrEquals(tok,"NoDeskSort"))
         flags |= NO_DESK_SORT;
       else if (StrEquals(tok,"UseIconName"))
@@ -362,6 +368,14 @@
   {
     return;
   }
+  if (iconified_at_end)
+  {
+    iconifiedList = malloc(numWindows*sizeof(t));
+    if (iconifiedList == NULL)
+    {
+      return;
+    }
+  }
   /* get the windowlist starting from the current window (if any)*/
   t = get_focus_window();
   if (t == NULL)
@@ -376,13 +390,24 @@
   {
     if (do_reverse_sort_order)
       windowList[numWindows - ii - 1] = t;
+    else if (iconified_at_end && IS_ICONIFIED(t))
+      iconifiedList[ic++] = t;
     else
-      windowList[ii] = t;
+      windowList[ii - ic] = t;
     if (t->next)
       t = t->next;
     else
       t = Scr.FvwmRoot.next;
   }
+  if (iconified_at_end && ic > 0)
+  {
+    if (current_at_end)
+      windowList[numWindows - 1] = windowList[--ii - ic];
+    for (ij = 0; ij < ic; ij++)
+    {
+      windowList[ij + (ii - ic)] = iconifiedList[ij];
+    }
+  }
 
   /* Do alphabetic sort */
@@ -597,6 +622,8 @@

---

From: Mikhael Goikhman <[email-masked]>
Date: Tue, 30 Apr 2002 11:19:23 +0000

> Ok, how's this?  Patched against cvs current, default branch.

Good, I have applied your IconifiedAtEnd patch.

Regards,
Mikhael.