Subject: Re: FVWM: Idea: Improved Window List Menu

From: Mikhael Goikhman <[email-masked]>
Date: Fri, 1 Nov 2002 22:44:11 +0000

On 01 Nov 2002 15:59:54 +0100, Dominik Vogt wrote:
> 
> On Fri, Nov 01, 2002 at 12:53:56AM -0500, Chris McCarthy wrote:
> > 
> > 	Now for my IDEA:  
> > 	
> > When I click right mouse button, I get a menu of all active windows.
> > What I would like to do is allow this menu to be sorted according to
> > the name of the window in 1 or 2 ways:
> > 
> > 1.)   All windows with the same file extension or same name (ie xterm, or 
> > 	.c ) would be color-coded the same color.
> > 	
> > 2.) Even better, the menu would include submenus, ie all windows with file
> > 	extensions ".c", then look under that list, etc.
> 
> What we really need is to allow calling an external program that
> filters and sorts the windows and generates the labels of the menu
> entries.

I really don't think this is what we need. Because you will need to pass
to this external program everything you normally pass to a module for it
to be flexible. At this point this program should be just a module.

Scripts are good when they get an input from other places like filesystem.
Not when they can't be run without fvwm giving them an input.

> > Could these ideas be implemented in future (or present) versions of
> > FVWM?
> 
> I can't promise how long it will take, but a generic soring
> interface would save us a lot of future work.

I am not sure what this means exactly, but this does not help Chris
McCarthy, he wants grouping not sorting.

You don't need to change any fvwm code to implement what Chris wants.
Currently a module that does this using perllib should be about 50 lines.
It will be 30 lines (mostly grouping/sorting entries by class/resource and
printing the main windowlist menu and its submenus) when automatical
trackers will be ready. I will write such module as a test case later.

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

---

From: Richard Lister <[email-masked]>
Date: Fri, 01 Nov 2002 18:04:38 -0500 (EST)

> trackers will be ready. I will write such module as a test case later.

Mikhael

As I mentioned in another thread, I've already implemented this.
I ported it to the 2.5.4 perllib, which was very straightforward.

Let me know if you want me to post it. I've included a screenshot
of the menu generated.

Is there any info online about the automatic trackers you are
implementing? 

Ric

Cheers
Ric

Richard J Lister
Dept of Neuroscience
Georgetown University Medical Center
http://cns.georgetown.edu/~ric/

---

From: Mikhael Goikhman <[email-masked]>
Date: Sat, 2 Nov 2002 03:08:09 +0000

> Let me know if you want me to post it. I've included a screenshot

Actually, I will need to write a lot of small modules in addition to the
current 6 in cvs to test trackers, I may use your module as a test case.

> Is there any info online about the automatic trackers you are

Such info is not even in my head yet. I only know that this should be
somewhat powerful and easy to use and extend. :)

Take a look at TrackerFactory.pm in cvs or ftp.fvwm.org to get some ideas.

My plan is to get some module and see how trackers may help it.
For example, your module may use 3 trackers, WindowList (with "wininfo"
and probably "icons" options), ConfigInfo and PageInfo. Other trackers
may be: Colorsets, GlobalInfo and "stack" option to the WindowList.
Nothing is final at all, even the names "tracker" and "grabber".

You are as the library user may help with ideas and design.
If you want to participate, install cvs.
Just please keep in mind that this is not my first priority for November.

Regards,
Mikhael.

---

From: Dominik Vogt <[email-masked]>
Date: Sat, 2 Nov 2002 11:26:30 +0100

> Not when they can't be run without fvwm giving them an input.

Right.  All the necessary information must be passed to the
script.  This job is partially done by the module interface
already.

> McCarthy, he wants grouping not sorting.

Actually, I see no difference between "sorting" and "grouping".

> You don't need to change any fvwm code to implement what Chris wants.

Except the menu code to allow different item text colours.

> trackers will be ready. I will write such module as a test case later.

The thought of moving the WindowList functionality into a simple
script is appealing.  But I suspect that we will never be content
with the limited information that goes over the module interface.

--

Okay, I see one very important issue here.  On one hand we have
the wish of the users to have more control over the WindowList (or
other features).  On the other hand we have the module interface
and the perl lib.  Now, these two do not fit together very well:

 - The module interface is intended for programmers, not users.
 - You can not rely on a working perl installation.
 - Only few users can program perl scripts (not me).
 - /bin/sh and certain unix commands are available on every
   system.
 - The knowledge of writing shell scripts is much more widespread.

So, in my eyes the "perl module" approach is not for the
typical do-it-yoursef user but for developers and very experienced
users/hackers.  In addition, I won't be able to help people
implementing their perl scripts because I never learned perl (and
I don't want to because of its weird syntax).

The big question is:  how can we provide a powerful do-it-yourself
interface to the intermediate to advanced shell user?

Bye

Dominik ^_^  ^_^

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

---

From: Mikhael Goikhman <[email-masked]>
Date: Sat, 2 Nov 2002 21:04:24 +0000

> Actually, I see no difference between "sorting" and "grouping".

Different groups may be delimited or placed in submenus.

> Except the menu code to allow different item text colours.

He said a better solution would be to use submenus. :)

> > It will be 30 lines (mostly grouping/sorting entries by class/resource
> > and printing the main windowlist menu and its submenus) when automatical

Actually, the script will not be simple if it should implement all
WindowList options. Especially if this is a shell script.

I fully agree that the module interface is limited, it should be enhanced
and in some cases corrected. Still, it is pretty powerful already.

What is the script interface alternative you suggest?
Does it use 2 pipes, in and out, just like a module?

I know what you want. You want bashlib or maybe zshlib for writting fvwm
modules in sh language. Unfortunately, sh is not a programming language.
It depends on unix utilities that vary on different unices, even sed/awk.
I would like to help writting such library, but it is just impossible.
Contrary to this, you may use perl that works equally on all systems,
even on non-unix.

>  - Only few users can program perl scripts (not me).

Writting perl is not needed any more than writting C to use FvwmButtons.

>  - /bin/sh and certain unix commands are available on every

Do you agree to start to use an ancient sh instead of zsh, and non GNU
utilities (I always miss the most useful options)?

>  - The knowledge of writing shell scripts is much more widespread.

Sorry, I can't agree with this one. I am sure more people program C/C++
and Perl than sh. It is also the most ineffective and the less powerful.
I am also sure almost noone can write really portable large shell scripts,
maybe except for autoconf developers. And autoconf developers moved
to perl themselves, because text manipulation in sh is much more obscure.
Automake developers always used perl for processing Makefile.am.

> I don't want to because of its weird syntax).

It takes years to become a perl expert, I know.
But I am sure every programmer familar with the module interface may learn
the basics of Perl and OOP to start to use perllib. I am willing to
explain what test modules in tests/perl/module-* do to everyone who wants
to learn.

> interface to the intermediate to advanced shell user?

A solution may be to maintain a powerful module for every task with all
options users may want, so they should just choose the most suitable.
Or a user may get the code and tweak it a bit (replace sort order).

Another solution may be to enable parts of the configuration to be shell
commands (sorting function?). But it still will be a perl or C written
module that just passes the relevant input to a shell script and reads and
incorporates the output. This may be possible for very simple cases only,
and it can't be generic, because the input/output format is very specific.

Regards,
Mikhael.

---

From: Dominik Vogt <[email-masked]>
Date: Sun, 3 Nov 2002 23:28:04 +0100

> On 02 Nov 2002 11:26:30 +0100, Dominik Vogt wrote:
[snip]
> and in some cases corrected. Still, it is pretty powerful already.

First and foremost the module interface should be *designed* and
not just export random window information as it is needed.
Especially propagating the whole window flags structure to the
modules is a serious design flaw as it implicitly declares
internal fvwm structures as part fvwm's module interface.  I don't
like that a bit and it regulary forces me to break compatibility.

> Does it use 2 pipes, in and out, just like a module?

Yes, but stdin and stdout should suffice.

> modules in sh language.

"shlib", actually.  I always try to avoid zsh and especially bash
specifics when writing shell scripts.

> Unfortunately, sh is not a programming language.

Yes.  The number of portable unix commands is quite limited.
Fortunately, the user does not have to worry about it, only people
writing scripts for public use (i.e. the fvwm developers).

> Writting perl is not needed any more than writting C to use FvwmButtons.

Then how do I write my own sorting algorithm using perllib without
writing perl?

> utilities (I always miss the most useful options)?

Sure.  See above.

> and Perl than sh.

Yes, sure.  But I was talking about users, not programmers.  I am
quite convinced more people are able to write something like

  $ sort -t . -k 2,2 foo  # sort by extension

than writing an equivalent perl script or C program.

> It is also the most ineffective

Maybe from a point of resource usage, but don't forget ease of use.
(And module interface performance is horrible too.)

> and the less powerful.

What?!  You probably haven't seen my phone database written as a
shell script :-)

> explain what test modules in tests/perl/module-* do to everyone who wants

Yes, I don't disagree here.  I am just thinking about an interface
that allows non-programmers to do useful things on their own.

> and it can't be generic, because the input/output format is very specific.

I have to think more about this.  It would not be difficult to
make up an ad hoc interface that prints the available information
into stdin of a shell script, but I wonder how useful it would be.
Let's assume we can access every style flag and each member of the
window structure with

  $[windowstruct_flag.is_transient]
  $[windowstruct_member.layer]
  $[windowstyle_flag.do_start_iconic]
  ...

(I am still thinking about a good solution to do this).  And let
us ignore the problems arising by exporting the whole window
structure as an external interface.

With that, we could add a format string that generates output and
a command that processes it to the WindowList command:

  WindowList CustomSort \
    Format=`$n $w $[page.nx] $[page.ny]` \
    Command=`/bin/sh -c 'sort -t . -k 2,2 | \
     read A B C D; \
     /bin/echo \"$A\t${C}x${D}\" WindowId $w WindowListFunc'`

(Ignore all the portability issues and bugs in the command).
Fvwm would print a line according to the format for each window
and pass that as input to a script.

Bye

Dominik ^_^  ^_^

---

From: Mikhael Goikhman <[email-masked]>
Date: Mon, 4 Nov 2002 05:50:34 +0000

> Then how do I write my own sorting algorithm using perllib without

The question is why to require a user to write something non trivial as a
new window sorting algorithm instead of just implementing it for a user.
I.e. you (a user) request a new module option, I (maintainer) add it.
Or you add it yourself if this is just several perl lines.

I see only 2 good alternatives, adding a new option (easiest for a user)
and writting a new module (the most powerful).

Options may be configurable, not just boolean flags, see, for example,
"man FvwmIconMan | grep SortWeight".

> and pass that as input to a script.

I can't stop you from doing this. but for me this is not good. :)

  1) a lot of code is added and little is gained (as compared to modules)  
  2) this still does not do grouping (with Nop delimeters or/and submenus) 
  3) a user should spend an effort for parsing complex input in a language 
     not designed for data manipulations
  4) this is not extendible, you patched WindowList command only
  5) the format is too bound to the internal structures to give it to
     a user to parse. Note, the module library parses this for a user and
     gives him already meaningfully named structures.
  6) I think the real working example will be much more complex (even if
     we do not pass hundreds of flags, only window names)

Now, please attention, here is a complete module (will work soon when
trackers are done) that creates WindowList sorted by window class and
shows user defined fields. Try to read it like English.

	$module = new FVWM::Module;

	@windows = $module->grab('WindowList')->windows;
	@windows = sort { $a->res_class cmp $b->res_class } @windows;

	$module->send("DestroyMenu MyWindowList");
	$module->send("AddToMenu   MyWindowList"); 
	foreach $window (@windows)
	{
		$w = $window->win_id;
		$i = $window->icon_name;
		$r = $window->res_name;
		$module->send("+ '$r: $i' WindowId $w Iconify")
	}
	$module->send("Menu MyWindowList");

I don't know what may be simplier than this. You don't need to modify any
fvwm code, because module interface already supplies all the information.

And if you need to create submenus, you just first group windows
by their class, i.e. add this code after the sort line above:

	while (@windows)
	{
		@class_windows = shift @windows;
		$current_class = $class_windows[0]->res_class;
		push @class_windows, shift @windows
			while $current_class eq $windows[0]->res_class;

		# create submenu for @class_windows, like shown above
	}

Any chance you just use perl to write custom modules? :)

Regards,
Mikhael.

---

From: Dominik Vogt <[email-masked]>
Date: Mon, 4 Nov 2002 10:33:05 +0100

> new window sorting algorithm instead of just implementing it for a user.

In this specific case, because many users want a different sorting
algorithms.

>   1) a lot of code is added and little is gained (as compared to modules)  

No, it's very little code.  Just one additional option with a bit
of inter process communication.  And I will extend vcariable
expansion independently of any WindowList features anyway.

>   2) this still does not do grouping (with Nop delimeters or/and submenus) 

Not my example, but it's trivial to enhance the script.

>      not designed for data manipulations

But the unix shell command set is exactly designed for that case:
simple filtering and text manipulation tasks.  It's not very
versatile when it comes to multiple line operations, though.

>      a user to parse.

Yes, but please see is as an ad hoc example.  Once I fugre out how
to process style names via a table, the same name can be used
in various features:

   $[Style.Sticky]
   $[State.Sticky]
   Next (Sticky)
   Style foobar Sticky
   ...

>      Note, the module library parses this for a user and

> Any chance you just use perl to write custom modules? :)

Maybe you misunderstand my whole point.  It's not about if *I* can
write such a module (or shell script) or not.  And I do not doubt
that the perllib allows relatively simple access to much of the
internal window information.  My point is that very few people
are able and willing to write your example script.  So, this is
just something we could write for others but can hardly ask them
to write it themselves.  But then it would not help much to reduce
our work spent with maintenance and user support.

Bye

Dominik ^_^  ^_^

---

From: Richard Lister <[email-masked]>
Date: Tue, 05 Nov 2002 19:06:33 -0500 (EST)

Mikhael Goikhman <[email-masked]> wrote on Sat, 2 Nov 2002 03:08:09 +0000:
>
> Subject: Re: FVWM: Idea: Improved Window List Menu
>

Hi Mikhael

I've added optional page and desk-level resolution and some
documentation to the script. I've attached it here.

> somewhat powerful and easy to use and extend. :)

As far as I understand it the trackers will make most of the stuff
I've done in handlers redundant. Is that correct?

> Take a look at TrackerFactory.pm in cvs or ftp.fvwm.org to get some ideas.

Will do this later.

> Just please keep in mind that this is not my first priority for November.

Ditto on November :-)  But I'll take a look when I get a bit of time.

A bug in my script ... sticky windows are only listed on the desk
where they originated (were made sticky). This is not a problem
when changing page, as there seems to be a M_CONFIGURE_WINDOW packet
sent for each window in that case and I set the desk from that handler.
But these packets are not send for a change desk event. Why is that?
I could probably get round this by doing a Send_Windowlist when
M_NEW_DESK is caught, but that seems clunky :-)

Cheers
Ric

Richard J Lister
Dept of Neuroscience

#!/usr/bin/perl -w

=head1 VERSION

  $Id: FvwmLister.pl,v 2.2 2002/11/05 23:57:10 ric Exp $

=head1 AUTHOR

  Ric Lister <http://cns.georgetown.edu/~ric/>

=head1 DESCRIPTION

  Substitute for fvwm builtin WindowList, but written in Perl
  and easy to customize. Unlike FvwmIconMan or FvwmWinlist the
  module does not draw its own window, but instead creates a
  fvwm menu and asks fvwm to pop it up.

  By defining a set of regular expressions in @show, windows may
  be sorted into sections based on the regexp matching their
  title.

  Similarly, matches in @dontshow will be excluded from the list.

  Any windows not matching an element of @show or @dontshow will
  be placed in the last section of the menu.

=head1 USAGE

  Place this in e.g. your .fvwm2rc StartFunction
    
    Module FvwmLister

  Invoke the menu from .fvwmrc like this, for example:
    
    Key Menu A N SendToModule FvwmLister Root c c

  The arguments are any valid Menu arguments.

  Set module options, e.g.:

    *FvwmLister: Show ^Galeon|^Netscape
    *FvwmLister: Show ^emacs

  will define two sections containing respectively browsers, and emacs.
  Number of sections is unlimited. The strings are perl regular
  expressions that will be evaluated in m// context. See perlre(1).

  Similarly:

    *FvwmLister: DontShow ^Fvwm
    *FvwmLister: DontShow ^gkrellm

  will cause the menu to ignore windows with title beginning Fvwm or
  gkrellm.

  Other options:
    
    *FvwmLister: OnlyIconic {on|off}    ## show only iconified windows
    *FvwmLister: MiniIcon {0|1|2}       ## show mini icon: 0=never,
                                        ## 1=always, 2=icon windows only
    *FvwmLister: AllDesks {on|off}      ## show windows from all desks
    *FvwmLister: AllPages {on|off}      ## show windows from all pages
    *FvwmLister: ShowPosition {on|off}  ## show window position in ()
    *FvwmLister: Maxlen 32              ## max length in chars of entry
    *FvwmLister: Menu foobar            ## name of menu to popup
    *FvwmLister: MenuStyle foobarstyle  ## name of MenuStyle to apply
    *FvwmLister: Debug {-1,0,1,...}     ## level of debug info output

=cut

## default user options
my $opt = {
  onlyiconic   => 0,        ## only list iconified windows
  mini_icon    => 2,        ## 0=never, 1=always, 2=iconic windows only
  alldesks     => 0,        ## list windows on all desks
  allpages     => 0,        ## list windows on all pages
  showposition => 1,        ## show window position
  maxlen       => 32,       ## max chars for window name in menu
  menu         => "Lister", ## name of fvwm menu to create
  menustyle    => "Lister", ## name of fvwm menu style to use
};

## get size of your screen
my $screen;

## I would like a better way of getting screen dimensions!
open(XWININFO, "xwininfo -root|") || die "can't run xwininfo";
while ( <XWININFO> ) {
  $screen->{w} = $1 if /Width:\s*(\d+)/;
  $screen->{h} = $1 if /Height:\s*(\d+)/;
}
close(XWININFO);

## or hard-code it
# $screen->{w} = 1600;
# $screen->{h} = 1200;

##
## USER SHOULD NOT NEED TO CHANGE ANYTHING BELOW HERE
##

use strict;
use lib `fvwm-perllib dir`;
use FVWM::Module;
use FVWM::EventNames;

## some global vars
my (%window, $page, $desk);

## show = window matches to display in order, each entry defines a section
## dontshow = window matches to ignore, none of these will show up in the menu
my (@show, @dontshow);

## init the module
## set Debug = -1 for no messages at all
## set Debug = 0 to see my messages about window decisions
## set Debug = 1 to see also perllib messages about communication
my $module = new FVWM::Module(
			      Name => "FvwmLister",
			      Mask => M_WINDOW_NAME | M_STRING |
			      M_NEW_PAGE | M_NEW_DESK |
			      M_ADD_WINDOW | M_CONFIGURE_WINDOW |
			      M_DESTROY_WINDOW | M_END_WINDOWLIST |
			      M_ICONIFY | M_DEICONIFY | M_MINI_ICON |
			      M_CONFIG_INFO | M_SENDCONFIG,
			      Debug => -1,
			      );

$module->debug("starting " . $module->name);

## process module options
$module->addHandler(M_CONFIG_INFO, sub {
  my ($module, $event) = @_;

  my $modname = $module->name;
  return unless $event->_text =~ /^\*$modname(.*)$/;
  $_ = $1;

  ## get show array
  if ( /^show\s+(.*)$/i ) {
    push(@show, $1);
  }

  ## get dontshow array
  elsif ( /^dontshow\s+(.*)$/i ) {
    push(@dontshow, $1);
  }

  ## get mini_icon option
  elsif ( /^miniicon\s*(.*)/i ) {
    $opt->{mini_icon} = $1 if $1;
  }

  ## get all other options, arg of 'off' sets opt to 0
  elsif ( $1 =~ /^(\w+)\s*(\w+)/i ) {
    (my $arg1 = $1) =~ tr/A-Z/a-z/;
    $opt->{$arg1} = ($2 =~ /^off$/i) ? 0 : $2;
  }

  ## should probably do more error checking
});

## handler to get page and desk info
$module->addHandler(M_NEW_PAGE, sub {
  my ($module, $event) = @_;

  $desk = $event->_desk;

  $page = {
    x => $event->_vp_x,
    y => $event->_vp_y,
    h => $event->_vp_height,
    w => $event->_vp_width,
  }
});

$module->addHandler(M_NEW_DESK, sub {
  my ($module, $event) = @_;
  $desk = $event->_desk;
});

$module->addHandler(M_STRING, sub{
  my ($module, $event) = @_;
  &PopupMenu($event->_text);
});

$module->addHandler(M_ADD_WINDOW|M_CONFIGURE_WINDOW, sub {
  my ($module, $event) = @_;

  $window{$event->_win_id}->{desk} = $event->_desk;
  $window{$event->_win_id}->{x} = $event->_frame_x;
  $window{$event->_win_id}->{y} = $event->_frame_y;
});

$module->addHandler(M_DESTROY_WINDOW, sub {
  my ($module, $event) = @_;
  delete $window{$event->_win_id};
});

$module->addHandler(M_WINDOW_NAME, sub {
  my ($module, $event) = @_;
  $window{$event->_win_id}->{name} = $event->_name;
});

$module->addHandler(M_ICONIFY, sub {
  my ($module, $event) = @_;
  $window{$event->_win_id}->{iconic} = 1;
});

$module->addHandler(M_DEICONIFY, sub {
  my ($module, $event) = @_;
  $window{$event->_win_id}->{iconic} = 0;
});

$module->addHandler(M_MINI_ICON, sub {
  my ($module, $event) = @_;
  $window{$event->_win_id}->{mini_icon} = $event->_name;
});

## does all the work and pops up the menu
sub PopupMenu {
  my($menu_args) = @_;

  my @section;

  ## loop on list of windows
  foreach my $id ( keys %window ) {

    $module->debug("\t$id - " . $window{$id}->{name});

    ## skip windows in the dontshow array
    my $dont_show_me;
    foreach ( @dontshow ) {
      $dont_show_me = 1, last if $window{$id}->{name} =~ /$_/;
    }

    $module->debug("\t\tin dontshow list"), next
	if $dont_show_me;

    ## skip windows not on this desk if alldesks not set
    $module->debug("\t\tnot on this desk"), next
	unless $opt->{alldesks} || ($window{$id}->{desk} == $desk);

    ## show only iconic windows if onlyiconic set
    $module->debug("\t\tskipping because not iconified"), next
	if $opt->{onlyiconic} && (not $window{$id}->{iconic});

    ## skip window if its top left is not on this page
    if ( ( not $opt->{allpages} ) &&
	($window{$id}->{x} < 0 || $window{$id}->{x} >= $screen->{w} ||
	 $window{$id}->{y} < 0 || $window{$id}->{y} >= $screen->{h}) )
    {
      $module->debug("\t\tnot on this page");
      next;
    }

    ## loop on sections and choose which one to file in
    my $sectctr = 0;
    foreach ( @show ) {
      last if $window{$id}->{name} =~ /$_/ ;
      ++$sectctr;
    }

    ## if we got here add the window to the last section
    ## which is 'none of the above'
    $module->debug("\t\tadding to section $sectctr");
    &AddToSection(\$section[$sectctr], $id);
  }

  ## tell fvwm to start the menu
  $module->send("DestroyMenu " . $opt->{menu});
  $module->send("AddToMenu " . $opt->{menu} . " \"Desk $desk, Page +" .
		$page->{x} . "+" . $page->{y} . "\" Title");

  ## now loop on sections sending menu entries to fvwm
  while ( @section ) {
    my $s = shift @section;

    if ( $s ) {
      $module->send($s);

      ## add separator after section unless this is last section
      $module->send("+ \"\" Nop") if ( @section );
    }
  }

  ## set a menustyle if one given
  $module->send("ChangeMenuStyle " . $opt->{menustyle} . " " . $opt->{menu})
      if $opt->{menustyle};

  ## popup the menu with args we were sent
  $module->send("Menu " . $opt->{menu} . " " . $menu_args);
}

## build a line containing the fvwm menu entry for a window
## then add it to the appropriate member of the global array @section
## args: pointer to section, window id
sub AddToSection {
  my($s, $id) = @_;

  ## shorten menu entry
  my $entry = substr($window{$id}->{name}, 0, $opt->{maxlen});

  ## add ellipses if we shortened entry
  $entry .= "..." if length($window{$id}->{name}) > $opt->{maxlen};

  ## add window position
  $entry .= "\t\t(" . $window{$id}->{x} . "x" . $window{$id}->{y} . ")"
      if $opt->{showposition};

  ## add desk number if we are in multi-desk mode
  $entry .= "\t(" . $window{$id}->{desk} . ")"
      if $opt->{alldesks};

  ## add mini_icon always (opt=1) or only to iconified programs (opt=2)
  my $mi = "";
  if ( ($opt->{mini_icon} == 1) or
       ($opt->{mini_icon} == 2 and $window{$id}->{iconic}) ) {
    $mi = "%" . $window{$id}->{mini_icon} . "%";
  }

  ## add the entry to the section
  $$s .= "+ \"$entry$mi\" WindowListFunc $id\n";
}

## main loop
$module->send("Send_ConfigInfo");
$module->send("Send_WindowList");
$module->eventLoop;

---

From: Richard Lister <[email-masked]>
Date: Tue, 05 Nov 2002 19:07:28 -0500 (EST)

> Except the menu code to allow different item text colours.

This, by the way, would be a really nice feature :-)

Ric

---

From: Mikhael Goikhman <[email-masked]>
Date: Wed, 6 Nov 2002 21:11:44 +0000

> documentation to the script. I've attached it here.

Nice, it is already pretty configurable. I see several possible
enhancements, not urgent though. And it is persistent. I thought
more about a transient module (yes, slower), this may be an option.

FvwmLister is a really good name for me, but maybe FvwmWindowLister?
You would probably prefer FvwmRichardLister, but this is close enough. :)

I will also reformat it to be more like FvwmPerl.

> I've done in handlers redundant. Is that correct?

Yes, in theory your module will not need to handle any of your current 13
fvwm events itself, except for M_STRING commands. It will just load 3
trackers instead. In practive, for now M_ICONIFY/M_DEICONIFY will be
needed too until perllib may reliably parse window flags (Sticky/Iconic)
given in M_CONFIGURE_WINDOW.

There will be a lot of decisions to make for trackers and you may help.
Just to give you another idea. A user may implement his own trackers.
For example, "ColorsetForcer", something that verifies that bg of Colorset
5 is always "green" or synchronizes 2 colorsets when one is changed.
Another example may be "VisibleWindows" that forces windows to never be
fully off the screen. Then a user may reuse these user defined trackers
in his numerous modules by adding this (only the first line is needed):

  my $tracker = $module->track("VisibleWindows", offset => 10);
  print "Recovered old window: $_\n" foreach $tracker->recovered;
  $tracker->trap(sub { print "Recovered new window: $_[0]\n"; });

Or a one time tracker that recovers the lost windows only once:

  my $grabber = $module->grab("VisibleWindows", offset => 10);
  print "Recovered old window: $_\n" foreach $grabber->recovered;

As you see, this implementation not only recovers windows internally (by
sending Move commands), but also optionally reports about such windows.
The problem is to decide what is the synchronous part (when these calls
return) and what is asynchronous. This is individual for every tracker.
There is no any problem if different trackers or a user himself decide to
listen to the same packets. Trackers are fully transparent for a user,
they just do their work (in your case they automatically collect an info).

> M_NEW_DESK is caught, but that seems clunky :-)

I have no debts that M_NEW_PAGE / M_NEW_DESK are inconsistent and pretty
unusable sometimes. The sooner we unite these to one M_NEW_DESK_PAGE the
better. A side note, the PageInfo tracker API will probably not be changed
when such packet change happens, just its internal implementation.

Regards,
Mikhael.

---

From: Richard Lister <[email-masked]>
Date: Wed, 06 Nov 2002 17:11:48 -0500 (EST)

> more about a transient module (yes, slower), this may be an option.

I originally coded it as transient, and that was acceptably
fast on a 600MHz PIII. I never tried it on a really slow machine.
Persistent just seemed a neater solution for some reason, maybe because
I use the menu all the time as an alternative to using up screen
space on iconman or icons. The nice thing about using a fvwm menu
is the automatic keybindings, so I do Menu G to find my galeon
windows, for example.

> You would probably prefer FvwmRichardLister, but this is close enough. :)

Yeah, it was just a play on my name :-) It might be nice to name it
something like FvwmPerlWinList or something very descriptive.
FvwmWindowLister is too similar to FvwmWinList.

> I will also reformat it to be more like FvwmPerl.

Fine.

> Just to give you another idea. A user may implement his own trackers.

This seems very cool. I'll take a look at the stuff in CVS in a
couple of days and see if I have any useful input for you.

Cheers
Ric

Richard J Lister
Dept of Neuroscience

---

From: Mikhael Goikhman <[email-masked]>
Date: Sat, 9 Nov 2002 09:44:44 +0000

> is the automatic keybindings, so I do Menu G to find my galeon

Yes, I find a menu to be very useful too. I usually don't use FvwmIconMan
even though I tried to use it, I find pager to be very useful and if there
are a lot of windows WindowList with SortByClass may help to identify them
quickly if you use good mini icons.

> FvwmWindowLister is too similar to FvwmWinList.

Hmm...

I returned to this message to say that I added the module and discovered
that I somehow missed anything except for the first page of this message.
I had a slow internet connection when I first read this message.

So, what should we do now when I coded it everywhere as FvwmWindowLister?
For me this name hints that it is a transient listing, so it's a good name.

> > I will also reformat it to be more like FvwmPerl.

At least here I guessed your answer correctly. :)

> couple of days and see if I have any useful input for you.

Ok, I did a lot of small changes, every change has its reason, take a look.

The module still misses some configurability like sorting, automatical
grouping, submenus, configurable format, class/resource/name resolution).
But it is a good start to test future trackers.

Regards,
Mikhael.

---

From: Richard Lister <[email-masked]>
Date: Tue, 12 Nov 2002 21:22:21 -0500 (EST)

> At least here I guessed your answer correctly. :)

I just downloaded the cvs snapshot and found you switched to 8-space
tab indentation, which was the worst thing I could have imagined :-)
Ah well, I suppose indentation styles are a bit of a religious war ...

> Ok, I did a lot of small changes, every change has its reason, take a look.

I think you broke the drawminiicon option, but I don't know this idiom:

    $foo = 0 + !!$1;

Otherwise, I like all the changes you made.

> But it is a good start to test future trackers.

I've added title/icon/class/resource matching with a syntax like:

  *FvwmWindowLister: Show resource = Galeon|Navigator|mozilla-bin

You can get the new version at:

  http://cns.georgetown.edu/~ric/software/fvwm/FvwmWindowLister

I even added emacs mode settings for your indentation style :-)

Cheers
Ric

Richard J Lister
Dept of Neuroscience

---

From: Richard Lister <[email-masked]>
Date: Wed, 13 Nov 2002 20:44:43 -0500 (EST)

I've added configurable menu formatting to FvwmWindowLister
and removed the DrawPosition and DrawMiniIcon options.

It's at

Let me know if there's a better way to submit this stuff.

Cheers
Ric

Richard J Lister
Dept of Neuroscience

---

From: Mikhael Goikhman <[email-masked]>
Date: Thu, 14 Nov 2002 05:19:55 +0000

> Let me know if there's a better way to submit this stuff.

I will comment on your other message later.
It is more convenient to get unified patches against FvwmWindowLister.in,
and not autogenerated FvwmWindowLister. Something like:

  cvs diff -u FvwmWindowLister.in >FvwmWindowLister.patch

or just (if you have a good .cvsrc):

  cvs diff >FvwmWindowLister.patch

Regards,
Mikhael.

---

From: Richard Lister <[email-masked]>
Date: Thu, 14 Nov 2002 13:13:30 -0500 (EST)

>   cvs diff >FvwmWindowLister.patch

OK, I thought that might be the case. I'm not really familiar with
cvs and autoconf but it seems pretty straightforward.

Ric

Richard J Lister
Dept of Neuroscience

---

From: Mikhael Goikhman <[email-masked]>
Date: Fri, 15 Nov 2002 09:45:20 +0000

> Ah well, I suppose indentation styles are a bit of a religious war ...

This is not really correct. I don't use 8-spaces, I use one tab. Unlike
our C code that requires TAB to be 8 spaces, our perl code is properly
structured to allow any TAB size. Use 4 spaces for TAB if you like this,
I use 3 or 8. Just please remember to write a properly structured code
(no spaces for indentation, no tabs in the middle of line) not to break
this TAB size freedom. I know, it is difficult with emacs...

> I think you broke the drawminiicon option, but I don't know this idiom:

It only veryfies that $foo ends up to be a number (you compare this with
numbers later, right?). But I forgot this is not a boolean (may be "2" as
well). I will fix this.

> I even added emacs mode settings for your indentation style :-)

I don't think these are the right settings, they insert 4 spaces.
In fact, I think the only way to configure emacs to do anything useful
is to disable auto-indentation and insert real tabs on tab press.

Regards,
Mikhael.

---

From: Richard Lister <[email-masked]>
Date: Fri, 15 Nov 2002 15:05:31 -0500 (EST)

> this TAB size freedom. I know, it is difficult with emacs...

OK, I think I understand what you mean. Use one tab for indentation, then
the programmer can choose to have their editor display tabs as
equivalent to whatever number of spaces they prefer. I agree this
is good and will switch to using this.

I think it ought to be straightforward with emacs once I figure it out.

> numbers later, right?). But I forgot this is not a boolean (may be "2" as

Don't worry, that option has gone away, replaced by the choice of
%M or %m in ItemFormat.

> is to disable auto-indentation and insert real tabs on tab press.

I'm confused as to what is happening. I screwed up the mode
settings, but they should have made emacs display the tabs as
equivalent to 8 spaces not 4. The file I put up definitely has
single tabs for indentation. Could it have got corrupted somewhere?

Anyway, I've got some more changes to add after the weekend. I'll
send those as a patch against CVS and it will hopefully be right
this time.

Thanks for the help.
Ric

Richard J Lister
Dept of Neuroscience