Hi Mikhael,

Find attached patch for the WindowList tracker.

I wonder if you would be adverse to renaming this tracker
"FVWM::Tracker::Window(s)"? This tracker tracks windows, not window lists.
What do you think?

Your fix to FVWM::Tracker::deleteHandlers works great!

Thanks,

SCoTT. :)
Index: WindowList.pm
===================================================================
RCS file: /home/cvs/fvwm/fvwm/perllib/FVWM/Tracker/WindowList.pm,v
retrieving revision 1.4
diff -u -r1.4 WindowList.pm
--- WindowList.pm       25 Oct 2003 03:00:01 -0000      1.4
+++ WindowList.pm       25 Apr 2004 08:18:49 -0000
@@ -20,11 +20,21 @@
 
 use FVWM::Tracker qw(base);
 
+my $windowEvents = M_ADD_WINDOW | M_CONFIGURE_WINDOW | M_DESTROY_WINDOW;
+my $nameEvents = M_RES_NAME | M_RES_CLASS | M_WINDOW_NAME | M_VISIBLE_NAME | 
M_ICON_NAME;
+my $stackEvents = M_RESTACK | M_RAISE_WINDOW | M_LOWER_WINDOW;
+my $iconEvents = M_ICON_LOCATION | M_ICON_FILE | M_DEFAULTICON | M_MINI_ICON;
+
 sub observables ($) {
        return [
                "window added",
                "window deleted",
                "window properties updated",
+               "window moved",
+               "window resized",
+               "window name updated",
+               "window stack updated",
+               "window icon updated",
        ];
 }
 
@@ -36,41 +46,36 @@
        my $self = $class->FVWM::Tracker::new($module);
 
        $self->{options} = [ @options ];
-
        return $self;
 }
 
-sub addRequestedInfoHandlers ($$$$) {
+sub addRequestedInfoHandlers ($$) {
        my $self = shift;
-       my $handlerC = shift;
-       my $handlerD = shift;
-       my $handlerP = shift;
+       my $handler = shift;
 
        my $useWInfo = 1;
        my $useNames = 1;
        my $useStack = 0;
        my $useIcons = 0;
-       foreach my $option (@{$self->{options}}) {  
+       foreach (@{$self->{options}}) {  
                /^(\!?)winfo$/ and $useWInfo = $1 ne '!';
                /^(\!?)names$/ and $useNames = $1 ne '!';
                /^(\!?)stack$/ and $useStack = $1 ne '!';
                /^(\!?)icons$/ and $useIcons = $1 ne '!';
        }
-       my $mask1  = 0;
-       my $mask2  = 0;
-       my $xmask2 = 0;
-       $mask1 |= M_ADD_WINDOW | M_CONFIGURE_WINDOW if $useWInfo;
-       $mask2 |= M_RES_NAME | M_RES_CLASS | M_WINDOW_NAME | M_VISIBLE_NAME | 
M_ICON_NAME
-               if $useNames;
-       $mask2 |= M_RESTACK | M_RAISE_WINDOW | M_LOWER_WINDOW if $useStack;  
-       $mask2 |= M_ICON_LOCATION | M_ICON_FILE | M_DEFAULTICON | M_MINI_ICON
-               if $useIcons;
-       $xmask2 |= MX_VISIBLE_ICON_NAME if $useNames;
-
-       $self->addHandler($mask1, $handlerC) if $mask1;
-       $self->addHandler(M_DESTROY_WINDOW, $handlerD);
-       $self->addHandler($mask2, $handlerP) if $mask2;
-       $self->addHandler($xmask2, $handlerP) if $xmask2;
+       my $mask  = 0;
+       $mask |= $windowEvents if $useWInfo;
+       $mask |= $nameEvents if $useNames;
+       $mask |= $stackEvents if $useStack;  
+       $mask |= $iconEvents if $useIcons;
+
+       # Adding MX_VISIBLE_ICON_NAME to $nameEvents does not work.
+       my $xmask = 0;
+       $xmask |= MX_VISIBLE_ICON_NAME if $useNames;
+
+       $self->addHandler($mask, $handler) if $mask;
+       $self->addHandler($xmask, $handler) if $xmask;
+       $self->addHandler(M_NEW_PAGE, sub { $self->handlerNewPage($_[1]); });
 }
 
 sub start ($) {
@@ -78,37 +83,62 @@
 
        $self->{data} = {};
 
-       ### TODO
        $self->addRequestedInfoHandlers(sub {
                my $event = $_[1];
-               $self->calculateInternals($event->args);
-       }, sub {
-               my $event = $_[1];
-               $self->calculateInternals($event->args);
-       }, sub {
-               my $event = $_[1];
-               $self->calculateInternals($event->args);
+               $self->calculateInternals($event);
        });
 
        $self->requestWindowListEvents;
-
-       ### temporary
-       $self->deleteHandlers;
-
        my $result = $self->SUPER::start;
-
        $self->deleteHandlers;
 
-       ### TODO
        $self->addRequestedInfoHandlers(sub {
                my $event = $_[1];
-               $self->calculateInternals($event->args);
-       }, sub {
-               my $event = $_[1];
-               $self->calculateInternals($event->args);
-       }, sub {
-               my $event = $_[1];
-               $self->calculateInternals($event->args);
+               my ($winId, $oldHash) = $self->calculateInternals($event);
+               return unless defined $winId;
+               my $type = $event->type();
+               if ($type & M_ADD_WINDOW)
+               {
+                       $self->notify("window added", $winId);
+               }
+               elsif ($type & M_CONFIGURE_WINDOW)
+               {
+                       $self->notify("window properties updated", $winId, 
$oldHash);
+                       # The "window properties updated" observable is very 
broad &
+                       # occurs as a result of many different operations - 
here we
+                       # try & determine if some common operations occur & 
invoke more
+                       # specific observables. This may reduce the amount of 
parsing
+                       # external modules have to do.
+                       my $p = $self->{data}->{$winId};
+                       if ($p->{frame_width} != $oldHash->{frame_width} ||
+                               $p->{frame_height} != $oldHash->{frame_height})
+                       {
+                               $self->notify("window resized", $winId, 
$oldHash);
+                       }
+                       elsif ($p->{desk} != $oldHash->{desk} ||
+                               $p->{x} != $oldHash->{x} ||
+                               $p->{y} != $oldHash->{y})
+                       {
+                               $self->notify("window moved", $winId, $oldHash);
+                       }
+                       # We can easily add other specific observables here as 
required.
+               }
+               elsif ($type & M_DESTROY_WINDOW)
+               {
+                       $self->notify("window deleted", $winId, $oldHash);
+               }
+               elsif ($type & $nameEvents || $type & MX_VISIBLE_ICON_NAME)
+               {
+                       $self->notify("window name updated", $winId, $oldHash);
+               }
+               elsif ($type & $stackEvents)
+               {
+                       $self->notify("window stack updated", $winId, $oldHash);
+               }
+               elsif ($type & $iconEvents)
+               {
+                       $self->notify("window icon updated", $winId, $oldHash);
+               }
        });
 
        return $result;
@@ -116,10 +146,41 @@
 
 sub calculateInternals ($$) {
        my $self = shift;
-       my $args = shift;
+       my $event = shift;
+       my $args = $event->args;
        my $data = $self->{data};
 
-       ### TODO
+       my $winId = $args->{win_id};
+       my $oldHash = undef;
+       if (defined $data->{$winId})
+       {
+               # make a copy of the hash cos we are about to modify it.
+               my %tmp = %{$data->{$winId}};
+               $oldHash = \%tmp;
+       }
+       @{$data->{$winId}}{keys %{$args}} = values %{$args};
+
+       if (defined $args->{frame_x})
+       {
+               # frame_x & frame_y are _relative_ coords of the window to the
+               # current page - calculate the _absolute_ coords - x & y.
+               my $p = $self->{pageInfo};
+               $data->{$winId}->{x} = $p->{currentPageX} + $args->{frame_x};
+               $data->{$winId}->{y} = $p->{currentPageY} + $args->{frame_y};
+       }
+
+       return wantarray ? ($winId, $oldHash) : $winId;
+}
+
+sub handlerNewPage ($$) {
+       my $self = shift;
+       my $event = shift;
+       my $args = $event->args;
+
+       $self->{pageInfo}->{currentPageX} = $args->{vp_x};
+       $self->{pageInfo}->{currentPageY} = $args->{vp_y};
+       $self->{pageInfo}->{pageWidth} = $args->{vp_width};
+       $self->{pageInfo}->{pageHeight} = $args->{vp_height};
 }
 
 sub data ($;$) { 
@@ -161,22 +222,27 @@
     "window added",
     "window deleted",
     "window properties updated",
-
-NOT USABLE YET.
+       "window moved",
+       "window resized",
+       "window name updated",
+       "window stack updated",
+       "window icon updated",
 
 =head1 SYNOPSYS
  
 Using B<FVWM::Module> $module object (preferably):
 
-    my $windowsTracker = $module->track("ModuleConfig");
+    my $windowsTracker = $module->track("WindowList", $options);
     my $windows = $windowsTracker->data;
     my $windowSizeX = $windows->{$winId}->{'x'};
 
 or:
 
-    my $windowsTracker = $module->track("WindowList");
+    my $windowsTracker = $module->track("WindowList", $options);
     my $windowSizeX = $windowsTracker->data($winId)->{'x'};
 
+Default $options string is: "!stack !icons names winfo"
+
 =head1 OVERRIDDEN METHODS
 
 =over 4
@@ -200,7 +266,7 @@
 
 =head1 AUTHOR
 
-Mikhael Goikhman <[EMAIL PROTECTED]>.
+Mikhael Goikhman <[EMAIL PROTECTED]>, Scott Smedley.
 
 =head1 SEE ALSO
 

Reply via email to