Taviso's WindowList function -- FvwmExpose

I found one interesting config by taviso. Cannot get it to work. Any help? On Fvwm Beginners Guide - Advanced Functions scroll down to the end. Here is an example of what that menu will look like.

What isn’t working? You do have both xwd and imagemagick installed?

Looking at the function, I notice it uses a bad environment variable (I was a bit of a noob when I wrote that), and you should use $[FVWM_USERDIR] vs $[fvwm_home]. You also need to make sure you have created the directory $[FVWM_USERDIR]/tmp or adjust that to point to a tmp directory to store the .png files in. If that directory doesn’t exist, the shell script will most likely fail.

xwd and imagemagick work fine. I am using this thumbnail sample in another config. Also did a test if the problem is with Fvwm3 by running 2.6.8. Cannot get the menu to appear (I am using FvwmConsole).

What about my other comments? Did you both update the environment variable (in two locations) and ensure that the tmp directory you are storing the .png files in exists?

Did the correction before you posted. When running the config, no thumbnails appear in /tmp.
I am assuming the problem is WindowID. Not familiar with this command. How to test if it works?

The thumbnails should be in $[FVWM_USERDIR]/tmp not /tmp, if the .png images are not in the desired directory, the issue is the xwd command piped to convert not creating these images, so you may want to manually test that part from a shell.

You can use the man page, though it appears the man page calls it WindowId, though fvwm is not case sensitive, this won’t matter. Here is the output of the man page from 2.6.x – basically it is a conditional that runs an fvwm command on a specific window:

              WindowId [id] [(conditions)] | [root [screen]] command
                     The WindowId command looks for a specific window id and runs the specified command
                     on it.  The second form of syntax retrieves the window id of the root window of
                     the given screen.  If no screen is given, the current screen is assumed.  The
                     window indicated by id may belong to a window not managed by fvwm or even a window
                     on a different screen.  Although most commands can not operate on such windows,
                     there are some exceptions, for example the WarpToWindow command.  Returns -1 if no
                     window with the given id exists.  See Conditions section for a list of conditions.

                     This command implies the conditions CirculateHit, CirculateHitIcon and
                     CirculateHitShaded.  They can be turned off by specifying !CirculateHit etc.
                     explicitly.

                     Examples:

                         WindowId 0x34567890 Raise
                         WindowId root 1 WarpToWindow 50 50
                         WindowId $0 (Silly_Popup) Delete

                     In the past this command was mostly useful for functions used with the WindowList
                     command, or for selective processing of FvwmEvent calls (as in the last example),
                     but currently these handler functions are called within a window context, so this
                     command is not really needed in these cases.  Still it may be useful if, for
                     example, the window id should be stored in the environment variable for a further
                     proceeding.

                         Pick SetEnv BOOKMARKED_WINDOW $[w.id]
                         WindowId $[BOOKMARKED_WINDOW] WarpToWindow

The excerpt of the man page that you posted, I read earlier. When I run the example in FvwmConsole,

WindowId 0x34567890 Raise
WindowId root 1 WarpToWindow 50 50
WindowId $0 (Silly_Popup) Delete

… nothing appears. Do you have one simple config with WindowId? Another question, does WindowId require a dependency package that may be missing in my system?

Got the FvwmExpose to work. I forgot its an AddToFunc. At the end of config, to add FvwmExpose.

DestroyFunc FvwmExpose
AddToFunc FvwmExpose
+ I AddToMenu FvwmExposeMenu "e x p o s e" Title
+ I + DynamicPopDownAction DestroyMenu FvwmExposeMenu
+ I All (!Iconic !Shaded AcceptsFocus)\
    PipeRead "echo Raise; \
        xwd -silent -id $[w.id] | convert -scale $$(($[w.width]/10)) -quality 0 xwd:- \
        png:$[FVWM_USERDIR]/tmp/icon.exp.$[w.id].png \
    && echo AddToMenu FvwmExposeMenu \
    %$[FVWM_USERDIR]/tmp/icon.exp.$[w.id].png%\\\'\"$[w.name]\"\\\' WindowId $[w.id] WarpToWindow 50 50 \
        && echo AddToMenu FvwmExposeMenu \\\"\\\" Nop \
    || Nop"
+ I Popup FvwmExposeMenu
+ I Exec exec rm -f $[FVWM_USERDIR]/tmp/icon.exp.*

FvwmExpose

Or add it in a binding or menu. This would be good to include in the Beginner’s Guide, as well as change the variable.

The Beginner’s Guide is out dated and I don’t want to go through and update all the environment variables that are not nicely used (the guide defines these new variables, but overall this isn’t the best way to go about things). As for your config, I do hope that those who use that function understand it is a function. If you want you could write up a page for the FvwmWiki on it, and maybe add comments about how this function can be bound to keys/mouses/FvwmButtons/and so on. But I don’t think adding FvwmExpose to the end of the block will help make it more usable.

I had a closer look at Taviso’s config. It’s good and useful with a minor edit. The filter selects items to expose, cleaner with CurrentPage, $[w.class] instead of $[w.name], and $[page.nx] - $[page.ny] in the title + binding. With the thumbnails and customization, it’s better than WindowList.

SetEnv cache $[FVWM_USERDIR]/cache

+I All (!Fvwm*, !Bruch*, !Tool*, CurrentPage, !Shaded, AcceptsFocus)
PipeRead "echo Lower;

%$[cache]/icon.exp.$[w.id].png%\’"$[w.class]"\’ WindowId

Mouse 2 R A FvwmExpose

fvwmExpose-currentPage

It would be good also to filter file extensions, such as !*.sys but could not find a variable for this.

Edit: Took me a second to get the above to work. It should be noted that it needs to be called with NoWindow first.

Example binding:

Key w a 4 NoWindow FvwmExpose

This is the config I am using without “NoWindow” in mouse binding. Folder cache/ included.

SetEnv cache $[FVWM_USERDIR]/cache

DestroyFunc FvwmExpose
AddToFunc FvwmExpose
+ I AddToMenu FvwmExposeMenu " W I N D O W  L I S T  $[page.nx] - $[page.ny]"  Title
+ I + DynamicPopDownAction DestroyMenu FvwmExposeMenu
+ I All (!Fvwm*, !Bru*, !Tool*, CurrentPage, !Shaded, AcceptsFocus)\
    PipeRead "echo Lower; \
        xwd -silent -id $[w.id] | convert -scale $$(($[w.width]/10)) -quality 0 xwd:- \
        png:$[cache]/icon.exp.$[w.id].png \
    && echo AddToMenu FvwmExposeMenu \
    %$[cache]/icon.exp.$[w.id].png%\\\'\"$[w.class]\"\\\' WindowId $[w.id] WarpToWindow 50 50 \
        && echo AddToMenu FvwmExposeMenu \\\"\\\" Nop \
    || Nop"
+ I Popup FvwmExposeMenu
+ I Exec exec rm -f $[cache]/icon.exp.*

Mouse 2 R A FvwmExpose #(mouse middle-click)

Cool. Have you had any issues with it? I’m finding this works great except sometimes it selects the wrong window of the same class, e.g. if I have two firefox windows, I get a menu entry for each, but sometimes it selects the wrong one.

Edit: This may be a problem with firefox, as I can’t reproduce it on other windows that are the same application.

You shouldn’t use environment variables, instead use InfoStore if you want to store local variables inside of fvwm.

Also with Chromium, thumbnail shot overlaps with other windows.

This is not the problem. Change PipeRead "echo Lower; to "echo Raise; as per Taviso’s original. I changed to Lower because Raise lowers the front-focused window. Changes the window layer order which looks confusing. I am still searching for a better solution.

Yeah. This at least stores the current window in CURRENTWINDOW and raises it again after the menu is built. It doesn’t preserve the layering of the other windows though.

AddToFunc FvwmExpose
+ I Current SetEnv CURRENTWINDOW $[w.id]
+ I AddToMenu FvwmExposeMenu "Expose" Title
+ I + DynamicPopDownAction DestroyMenu FvwmExposeMenu
+ I All (!Iconic !Shaded AcceptsFocus CurrentPage) \
    PipeRead "echo Raise; \
        xwd -silent -id $[w.id] | convert -scale 128 -frame 1x1 -mattecolor white -quality 0 xwd:- \
        png:$[FVWM_USERDIR]/tmp/icon.exp.$[w.id].png \
    && echo AddToMenu FvwmExposeMenu \
    %$[FVWM_USERDIR]/tmp/icon.exp.$[w.id].png%\\\'\"$[w.class]\"\\\' WindowId $[w.id] FocusRaise\
        && echo AddToMenu FvwmExposeMenu \\\"\\\" Nop \
    || Nop"
+ I WindowId $[CURRENTWINDOW] WarpToWindow
+ I Menu FvwmExposeMenu Root c c
+ I Exec exec rm -f $[FVWM_USERDIR]/tmp/icon.exp.*

Not the best solution but better if the front-focused window, which is lowered to the bottom, could raise again at end of the script. How?

That’s what the above function does. I use WarpToWindow, but you could use Raise. If you close the menu before making a selection it should focus back in to the previous window.

+ I Current SetEnv CURRENTWINDOW $[w.id]
+ I WindowId $[CURRENTWINDOW] WarpToWindow

In my hurry, I didn’t see your config. Did a test. It keeps the order, uniformed thumbnail size, but does not allow to select the preferred window.

You mean selecting windows from the menu doesn’t do anything? If so, that’s odd. It works for me (keyboard focus).