Use window variables to select Style details?

Basic FVWM questions can be asked here.
porcupine
Kitten
Kitten
Posts: 8
Joined: Wed Dec 20, 2017 6:15 am

Use window variables to select Style details?

Postby porcupine » Wed Dec 20, 2017 6:40 am

Hi!

I'd like to select particular MiniIcons (for example) using more than
one of the window name, class, visible name, and resource string.
In this particular case, I have mini icons of different shapes
for an xterm session at the shell prompt or one running vim, and
different colours depending on which host is connected to.

The class matches XTerm for all of the xterms, the visible name
matches "VIM" when vim is in use, and I can get the hostname from
the icon name (which I set when starting the xterm). I wish I
could do something like this:

Style "XTerm" MiniIcon mini_xterm_$[w.iconname].xpm
Style "*VIM*" MiniIcon mini_vim_$[w.iconname].xpm

but this doesn't work, so I assume I can't use a variable name in that
spot, or in that way, or the "w" variables aren't set at that point...

How can I approach this? Is what I want even possible?

Anne.

phleagol
Cat in the hat
Cat in the hat
Posts: 48
Joined: Sun Nov 24, 2013 1:19 pm
Location: New Zealand

Re: Use window variables to select Style details?

Postby phleagol » Wed Dec 20, 2017 9:35 pm

porcupine wrote: How can I approach this? Is what I want even possible? Anne.

Perhaps something like this ?

Code: Select all

##  Default miniicon
Style XTerm Miniicon mini_xterm.xpm

##  Runs XtermMiniiconFunc for each new window.
Style XTerm InitialMapCommand XtermMiniiconFunc

DestroyFunc XtermMiniiconFunc
AddToFunc   XtermMiniiconFunc
+ I ThisWindow (hostname1) WindowStyle Miniicon mini_host1.xpm
+ I ThisWindow (hostname2) WindowStyle Miniicon mini_host2.xpm
+ I ThisWindow (hostname3) WindowStyle Miniicon mini_host3.xpm

porcupine
Kitten
Kitten
Posts: 8
Joined: Wed Dec 20, 2017 6:15 am

Re: Use window variables to select Style details?

Postby porcupine » Thu Dec 21, 2017 6:01 am

Thanks for introducing me to the InitialMapCommand! Interesting.

But in this case, since I already set the resource name to
"hostname-session" when I fire up the window (with xterm -name
$hostname-session), I'm not sure that your proposal is all that
different from what I have now, which is something like:

Style "pandora-session" MiniIcon mini_xterm_pandora.xpm
Style "quill-session" MiniIcon mini_xterm_quill.xpm

... and so on. Also, it doesn't address switching the MiniIcon to
a host-specific "vim" icon when vim is in use, then reverting to
the host-specific "xterm" icon when vim exits.

I'm starting to look at what I can get vim to do for me with
"titlestring"; I can probably get "hostname-vim" in there, and then
match on that. I'd still be using enumerations, but at least I'd get
the behaviour I want, I think.

Again it would be cool if it could be done with window variables
instead of enumerations, but I'm starting to suspect that fvwm
syntax simply doesn't support that.

That "InitialMapCommand" is neat in that the use of a function
allows the use of conditional statements, and the conditional
statements can be multiple - I think that does lead somewhere useful!
But InitialMapCommand is invoked just once "when the window is
initially mapped" - I don't, offhand, see a way to invoke a function
whenever (for example) the visible name changes.

This is all quite encouraging; thank you!

Anne.

phleagol
Cat in the hat
Cat in the hat
Posts: 48
Joined: Sun Nov 24, 2013 1:19 pm
Location: New Zealand

Re: Use window variables to select Style details?

Postby phleagol » Thu Dec 21, 2017 8:10 am

porcupine wrote:But InitialMapCommand is invoked just once "when the window is
initially mapped" - I don't, offhand, see a way to invoke a function
whenever (for example) the visible name changes.

In that situation, the FvwmEvent Module might help. It happily triggers on name changes etc.

Code: Select all

##  Uncomment either "visible_name" or "visible_icon_name"
DestroyModuleConfig FvwmEvent: *
*FvwmEvent: Cmd Function
*FvwmEvent: visible_name        SomeFunc
#*FvwmEvent: visible_icon_name  SomeFunc

DestroyFunc SomeFunc
AddToFunc   SomeFunc
+ I Echo * Your stuff here...

##  Start FvwmEvent module
KillModule FvwmEvent
Schedule 1000 Module FvwmEvent

thomasadam
Administrator
Administrator
Posts: 3046
Joined: Mon Nov 08, 2004 1:12 am
Location: England
Contact:

Re: Use window variables to select Style details?

Postby thomasadam » Thu Dec 21, 2017 2:23 pm

porcupine wrote:I'm starting to look at what I can get vim to do for me with
"titlestring"; I can probably get "hostname-vim" in there, and then
match on that. I'd still be using enumerations, but at least I'd get
the behaviour I want, I think.


Style lines only apply for windows being mapped, not when attributes about a window change. Although I can see you been directed towards "visible_name" in FvwmEvent as a solution, this is only going to get you so far before you need to rethink your approach, simply because you can't make any guarantees about the application changing its name.

Furthermore, *visible_name* is only applicable for a window's title -- and there's no guarantee about how applications set that, either. You can probably get away with it if it's XTerm, but as you're finding out, you're having to rely on application inside being able to set that. Hence, I'm dubious what point you think setting the window's resource and hostname is going to achieve -- you can always pull these out of FVWM with $[w.<thing>].

I would suggest you use State instead on these windows and get those conditions to influence a window's state, and then you can get FVWM to act accordingly.

-- Thomas Adam

porcupine
Kitten
Kitten
Posts: 8
Joined: Wed Dec 20, 2017 6:15 am

Re: Use window variables to select Style details?

Postby porcupine » Sat Dec 23, 2017 6:25 am

First, a big thank you to phleagol for pointing me towards the FvwmEvent module; because I'd been repeatedly restarting the window manager to see the effect of my configuration changes, it hadn't dawned on me that (under normal circumstances) they would be applied only when the window started up, so I would have set up all my styles only to find out later that they were not applied when the window changed! You've saved me a lot of annoyance. ;-)

Thanks also for supplying a code snippet to get me started. Despite having used fvwm for probably close to two decades, my needs have been simple and I'd never tried to use modules before. But I've spent the evening playing with this and it's very cool! I think I'm pretty close to getting it to do what I need.

thomasadam wrote:Style lines only apply for windows being mapped, not when attributes about a window change. Although I can see you been directed towards "visible_name" in FvwmEvent as a solution, this is only going to get you so far before you need to rethink your approach, simply because you can't make any guarantees about the application changing its name.


As it happens, though, the applications I'm interested in are xterm at a tcsh prompt, xterm running vim, and firefox; with the first two, I can control the window name change, and with the last, I'm satisfied with the app's behaviour in this respect.

thomasadam wrote:Furthermore, *visible_name* is only applicable for a window's title -- and there's no guarantee about how applications set that, either. You can probably get away with it if it's XTerm, but as you're finding out, you're having to rely on application inside being able to set that. Hence, I'm dubious what point you think setting the window's resource and hostname is going to achieve -- you can always pull these out of FVWM with $[w.<thing>].


I'm putting various pieces of information into the window's icon name and title precisely so I can use them in my fvwmrc to select icons and set labels. I suspect I didn't understand your question. :-(

thomasadam wrote:I would suggest you use State instead on these windows and get those conditions to influence a window's state, and then you can get FVWM to act accordingly.


I'll keep that idea in mind if a simpler approach doesn't do the trick. But if I understand correctly what you're suggesting, I think I'd generate too many states, because I'd need a state for each hostname/app combo, and I have dozens of them.

I'm going to learn the syntax of the conditional commands in functions, and if the syntax is insufficient to express what I want, I might just set a style by PipeReading out to a Perl script, to which I can feed the $[w.<thing>] fields I need to make my colour and icon selections.

The good part of all this is that I'm having fun learning how to make fvwm jump through hoops, and I'm grateful to you folks for your extremely useful input! Thanks again,

Anne.

phleagol
Cat in the hat
Cat in the hat
Posts: 48
Joined: Sun Nov 24, 2013 1:19 pm
Location: New Zealand

Re: Use window variables to select Style details?

Postby phleagol » Sat Dec 23, 2017 11:10 am

porcupine wrote:The good part of all this is that I'm having fun learning how to make fvwm jump through hoops, and I'm grateful to you folks for your extremely useful input! Thanks again,

You're welcome! Merry xmas porcupine.

porcupine
Kitten
Kitten
Posts: 8
Joined: Wed Dec 20, 2017 6:15 am

Re: Use window variables to select Style details?

Postby porcupine » Sat Dec 23, 2017 9:10 pm

Just a quick report; the following works (in conjunction with my using vim's "titlestring" to make sure the string I want is in the window's visible_name):

Code: Select all

DestroyModuleConfig FE-Styles: *
*FE-Styles: Cmd Function
*FE-Styles: visible_name        ChangeMiniIcon

DestroyModuleConfig FE-Sounds: *
*FE-Sounds: Cmd "Exec aplay"
*FE-Sounds: visible_name        /home/a/anne/.sounds/bell-1.wav

DestroyFunc ChangeMiniIcon
AddToFunc   ChangeMiniIcon
+ I Echo Window $[w.id] visible_name=$[w.visiblename]
+ I ThisWindow ("*-vim *") Echo "...is a vim window on $[w.iconname]"
+ I ThisWindow ("*-vim *") WindowStyle MiniIcon mini_vim_$[w.iconname].xpm
+ I ThisWindow (!"*-vim *") Echo "...is NOT a vim window $[w.iconname]"
+ I ThisWindow (!"*-vim *") WindowStyle MiniIcon mini_xterm_$[w.iconname].xpm

# Start FvwmEvent modules
KillModule FvwmEvent FE-Styles
Schedule 1000 Module FvwmEvent FE-Styles
KillModule FvwmEvent FE-Sounds
Schedule 1000 Module FvwmEvent FE-Sounds


(The sounds and Echo commands are temporary for debugging.)

I'm going to refine this some more, but I have proof of concept. :-)

Again, thank you, and happy holidays!

Anne.

thomasadam
Administrator
Administrator
Posts: 3046
Joined: Mon Nov 08, 2004 1:12 am
Location: England
Contact:

Re: Use window variables to select Style details?

Postby thomasadam » Sun Dec 24, 2017 2:21 am

porcupine wrote:

Code: Select all

DestroyFunc ChangeMiniIcon
AddToFunc   ChangeMiniIcon
+ I Echo Window $[w.id] visible_name=$[w.visiblename]
+ I ThisWindow ("*-vim *") Echo "...is a vim window on $[w.iconname]"
+ I ThisWindow ("*-vim *") WindowStyle MiniIcon mini_vim_$[w.iconname].xpm
+ I ThisWindow (!"*-vim *") Echo "...is NOT a vim window $[w.iconname]"
+ I ThisWindow (!"*-vim *") WindowStyle MiniIcon mini_xterm_$[w.iconname].xpm


You should use:

Code: Select all

DestroyFunc ChangeMiniIcon
AddToFunc   ChangeMiniIcon
+ I ThisWindow ("*-vim *") WindowStyle MiniIcon mini_vim_$[w.iconname].xpm
+ I TestRc (Match) Break
+ ...


This is because the conditional formatting of (!"foo*") won't match in the way you think it does for negations, where you're wanting to check the result of the previous command (hence using TestRc), Also, you made a lot of fuss about using the window's visiblename, and yet I don't see anything checking it here. Why?

porcupine wrote:

Code: Select all

# Start FvwmEvent modules
KillModule FvwmEvent FE-Styles
Schedule 1000 Module FvwmEvent FE-Styles
KillModule FvwmEvent FE-Sounds
Schedule 1000 Module FvwmEvent FE-Sounds



Don't start Modules like this. Use StartFunction for anything which is going into your configuration file. There's no need to Schedule this at all.

-- Thomas Adam

porcupine
Kitten
Kitten
Posts: 8
Joined: Wed Dec 20, 2017 6:15 am

Re: Use window variables to select Style details?

Postby porcupine » Wed Dec 27, 2017 9:41 am

thomasadam wrote:
porcupine wrote:

Code: Select all

DestroyFunc ChangeMiniIcon
AddToFunc   ChangeMiniIcon
+ I Echo Window $[w.id] visible_name=$[w.visiblename]
+ I ThisWindow ("*-vim *") Echo "...is a vim window on $[w.iconname]"
+ I ThisWindow ("*-vim *") WindowStyle MiniIcon mini_vim_$[w.iconname].xpm
+ I ThisWindow (!"*-vim *") Echo "...is NOT a vim window $[w.iconname]"
+ I ThisWindow (!"*-vim *") WindowStyle MiniIcon mini_xterm_$[w.iconname].xpm



You should use:

Code: Select all

DestroyFunc ChangeMiniIcon
AddToFunc   ChangeMiniIcon
+ I ThisWindow ("*-vim *") WindowStyle MiniIcon mini_vim_$[w.iconname].xpm
+ I TestRc (Match) Break
+ ...


This is because the conditional formatting of (!"foo*") won't match
in the way you think it does for negations, where you're wanting
to check the result of the previous command (hence using TestRc),


I'm puzzled; why won't it match the way I think it does for negations? I re-read the manpage yet again, and it states that "Each window name can begin with '!', which prevents command if any of the window name, icon name, class or resource match", which seems like what I want, and it was working, based on the Echo commands I had in there.

Now it's flakey again - the Echoes show the Right Thing, but the mini icons don't always get set. I think I'm going to end up working around all this (see below).

thomasadam wrote:Also, you made a lot of fuss about using the window's visiblename, and yet I don't see anything checking it here. Why?


Fuss is perhaps a big word ;-), but...

The expression "*-vim *" matches on the window's visiblename (or name, which in the case of all of the windows I've checked with xprop, is the same as the visiblename). Perhaps I've caused confusion and should have referred to the name. Perhaps there are situations where the two differ, though I haven't seen any in my modest set-up.

thomasadam wrote:
porcupine wrote:

Code: Select all

# Start FvwmEvent modules
KillModule FvwmEvent FE-Styles
Schedule 1000 Module FvwmEvent FE-Styles
KillModule FvwmEvent FE-Sounds
Schedule 1000 Module FvwmEvent FE-Sounds



Don't start Modules like this. Use StartFunction for anything which is going into your configuration file. There's no need to Schedule this at all.



Okay, I defer to your greater knowledge of best practice; I've moved
all my module start-ups to StartFunction. Thank you.

Meanwhile, now that I understand what modules can do, I've taken the next logical step and written one of my own, using FVWM::Module. Now I can grab a lot of info about the window using a call-out to "xprop -notype -id $window_id", and perform arbitrary actions based on any match I wish, using the full power of Perl regexps. I find that easier to code.

I have a proof of concept - at the moment I just cycle the BorderColorset and HilightBorderColorset through four arbitrary colours whenever the visiblename changes, and I log what I found out and calculated about the window upon that event. But I can probably set pretty much all I want (border and title colours, icons and mini icons) from this script, and simplify my fvwm config files in consequence.

I do wonder, though, if there's an easier way to grab the window properties from Perl, ideally through a subroutine call to an fvwm-supplied Perl module. Parsing xprop's output is kind of ugly.

Anne.

thomasadam
Administrator
Administrator
Posts: 3046
Joined: Mon Nov 08, 2004 1:12 am
Location: England
Contact:

Re: Use window variables to select Style details?

Postby thomasadam » Wed Dec 27, 2017 1:18 pm

porcupine wrote:I do wonder, though, if there's an easier way to grab the window properties from Perl, ideally through a subroutine call to an fvwm-supplied Perl module. Parsing xprop's output is kind of ugly.


There is. Look at Fvwm::Event::dump() for example.

-- Thomas Adam

porcupine
Kitten
Kitten
Posts: 8
Joined: Wed Dec 20, 2017 6:15 am

Re: Use window variables to select Style details?

Postby porcupine » Sun Jan 14, 2018 8:20 am

thomasadam wrote:
porcupine wrote:I do wonder, though, if there's an easier way to grab the window properties from Perl, ideally through a subroutine call to an fvwm-supplied Perl module. Parsing xprop's output is kind of ugly.


There is. Look at Fvwm::Event::dump() for example.


That seems to supply:

Code: Select all

DUMP: M_VISIBLE_NAME
   win_id       0x1200022
   frame_id     0x080058f
   ptr          40991568
   name         "quill     (anne)     /home/a/anne/.x/fvwmrc/modules "


... which is not nearly as much information as I get from xprop, but I know
that fvwm is tracking a lot more info than that about the window. Is one of
win_id, frame_id, or ptr a reference to an object or a data structure that I
can dereference or query to get at, for example, WM_CLASS and WM_ICON_NAME?

Anne.

phleagol
Cat in the hat
Cat in the hat
Posts: 48
Joined: Sun Nov 24, 2013 1:19 pm
Location: New Zealand

Re: Use window variables to select Style details?

Postby phleagol » Mon Jan 15, 2018 11:19 am

porcupine wrote: ...but I know that fvwm is tracking a lot more info than that about the window. Is one of win_id, frame_id, or ptr a reference to an object or a data structure that I can dereference or query to get at, for example, WM_CLASS and WM_ICON_NAME? Anne.

No, they are not references. M_VISIBLE_NAME only provide 4 arguments, but other event types do provide more arguments, as you can see here...

Code: Select all

fvwm-perllib man events

That aside, the WindowList tracker provides perhaps the most complete info for any given window, including class_name and icon_name. To read more...

Code: Select all

fvwm-perllib man FVWM::Tracker::WindowList
fvwm-perllib man index

porcupine
Kitten
Kitten
Posts: 8
Joined: Wed Dec 20, 2017 6:15 am

Re: Use window variables to select Style details?

Postby porcupine » Thu Jan 18, 2018 6:05 am

phleagol wrote:the WindowList tracker provides perhaps the most complete info for any given window, including class_name and icon_name.


That does seem interesting, but I've spent the evening trying in vain to make that work. I think I'm missing a fundamental insight somewhere.

I've been assuming I could just add the use of the WindowList tracker to my current module, which uses FVWM::Module, registers a bunch of handlers, and enters the event loop. When I try to create a tracker by calling "track" on the FVWM::Module object before telling it to enter the event loop, things just stop working at all.

Am I supposed to entirely replace the use of the FVWM::Module "addHandler" and "eventLoop" with "observe" calls to an FVWM::Tracker::WindowList object?

Anne.

phleagol
Cat in the hat
Cat in the hat
Posts: 48
Joined: Sun Nov 24, 2013 1:19 pm
Location: New Zealand

Re: Use window variables to select Style details?

Postby phleagol » Thu Jan 18, 2018 10:33 am

When I try to create a tracker by calling "track" on the FVWM::Module object before telling it to enter the event loop, things just stop working at all. Am I supposed to entirely replace the use of the FVWM::Module "addHandler" and "eventLoop" with "observe" calls to an FVWM::Tracker::WindowList object?

Perhaps windowlist tracker is not the simplest solution for your situation. Sorry about that. But if we avoid the tracker, and stick with just the event_loop, then class and names can be gathered with something like this...

Code: Select all

#!/usr/bin/perl
#  Get name and class for all windows then dump and exit.

use strict ;
use warnings ;
use lib `fvwm-perllib dir` ;
use FVWM::Module ;
use Data::Dump qw( dump ) ;

my $modname = "FvwmTest" ;
my $module = new FVWM::Module(
        Name => $modname,
        Mask => M_WINDOW_NAME | M_RES_CLASS | M_END_WINDOWLIST,
        Debug => 0,
        ) ;

my $ww  ;

$module->addHandler(M_WINDOW_NAME, sub {
    my ($module, $event) = @_ ;
    my $wid = $event->args->{win_id} ;
    $ww->{$wid}->{name} = $event->args->{name} ;
}) ;

$module->addHandler(M_RES_CLASS, sub {
    my ($module, $event) = @_ ;
    my $wid = $event->args->{win_id} ;
    $ww->{$wid}->{class} = $event->args->{name} ;
}) ;

# $module->addHandler(M_RES_NAME,       sub { ... }) ;
# $module->addHandler(M_ICON_NAME,       sub { ... }) ;
# $module->addHandler(M_VISIBLE_NAME,    sub { ... }) ;

##  Terminate FVWM::Module after windowlist completed. Just for this test...
$module->addHandler(M_END_WINDOWLIST, sub { $module->terminate }) ;

$module->send("Send_WindowList") ;
$module->event_loop ;

##  dump info after windowlist has finished.
dump $ww ;

porcupine
Kitten
Kitten
Posts: 8
Joined: Wed Dec 20, 2017 6:15 am

Re: Use window variables to select Style details?

Postby porcupine » Thu Jan 18, 2018 4:05 pm

phleagol wrote:
When I try to create a tracker by calling "track" on the FVWM::Module object before telling it to enter the event loop, things just stop working at all. Am I supposed to entirely replace the use of the FVWM::Module "addHandler" and "eventLoop" with "observe" calls to an FVWM::Tracker::WindowList object?

Perhaps windowlist tracker is not the simplest solution for your situation. Sorry about that.


Not a problem; I don't need the simplest solution, but I do need a working solution. As I mentioned earlier, I do have a working solution that involves calling xprop, but that's an extra process exec for every event, and parsing the output is somewhat ugly. Of greater concern is that I have to be a bit careful how hard I pound on the window system: at one point I was running my handler on "enter window" and "leave window" events as well, and that put fvwm into a wild loop - I had to ssh into my desktop from another host to kill the malfuncioning module.

But if we avoid the tracker, and stick with just the event_loop, then class and names can be gathered with something like this...


But unless I badly misunderstand your code, you're simply gathering information already supplied in the event object passed as a parameter to the handler. The problem I'm trying to solve is gathering additional information that I know is available to the window system and to fvwm, but is not contained in the event object. I need that information not about all windows each time, but just about the window whose event I'm processing. I'm given the window ID; is there a way within the FVWM modules ecosystem to use that window ID to obtain all information about that window?

Anne.

phleagol
Cat in the hat
Cat in the hat
Posts: 48
Joined: Sun Nov 24, 2013 1:19 pm
Location: New Zealand

Re: Use window variables to select Style details?

Postby phleagol » Thu Jan 18, 2018 10:31 pm

porcupine wrote:I'm given the window ID; is there a way within the FVWM modules ecosystem to use that window ID to obtain all information about that window?

I'd say the windowlist tracker. That seems to be its purpose. But only a limited range of information is available. For example, is a certain window titled or untitled? The tracker does not tell us.

porcupine wrote:When I try to create a tracker by calling "track" on the FVWM::Module object before telling it to enter the event loop, things just stop working at all.

I mostly use the windowlist tracker instead of using event_loop, and it works just fine. But I recall attempting to use the windowlist tracker and event_loop together, and being surprised by some problem. But that was a long time ago, and I didn't investigate further.

porcupine wrote:Am I supposed to entirely replace the use of the FVWM::Module "addHandler" and "eventLoop" with "observe" calls to an FVWM::Tracker::WindowList object?

Not sure. Someone else may know.


Return to “Basic questions”

Who is online

Users browsing this forum: No registered users and 3 guests