Skip to content

Commit 1ccdd6a

Browse files
committed
Fix watching specific files on windows
When you are only watching specific file paths, you get change events for all files in the same directory. On linux only changes to watched files get reported.
1 parent 24d4cad commit 1ccdd6a

1 file changed

Lines changed: 28 additions & 2 deletions

File tree

lib/Filesys/Notify/Simple.pm

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ sub mk_wait_win32 {
119119
return sub {
120120
my @path = @_;
121121

122+
my %watched = map { ( $_ => 1 ) }
123+
grep defined, map { Cwd::abs_path($_) } @path;
122124
my $fs = _full_scan(@path);
123125
my (@notify, @fskey);
124126
for my $path (keys %$fs) {
@@ -133,11 +135,35 @@ sub mk_wait_win32 {
133135

134136
my @events;
135137
while(1) {
136-
my $idx = Win32::ChangeNotify::wait_any(\@notify);
138+
my $idx = Win32::ChangeNotify::wait_any(\@notify);
137139
Carp::croak("Can't wait notifications, maybe ".scalar(@notify)." directories exceeds limitation.") if ! defined $idx;
138140
if($idx > 0) {
139141
--$idx;
142+
# get all file changes in path
140143
my $new_fs = _full_scan($fskey[$idx]);
144+
foreach my $root (keys %{$new_fs}) {
145+
# on windows we can only watch folders
146+
# therefore we need to filter unwanted
147+
# events for files we are not looking for
148+
unless (exists $watched{$root}) {
149+
# process all reported file changes in path
150+
foreach my $file (keys %{$new_fs->{$root}}) {
151+
# don't remove if we watch particular file
152+
unless (exists $fs->{$root}->{$file}) {
153+
# we are not interested in this event
154+
delete $new_fs->{$root}->{$file};
155+
}
156+
}
157+
}
158+
# but only if we don't watch folder itself
159+
else {
160+
# check if we watch particular root
161+
unless (exists $fs->{$root}) {
162+
# remove paths not watched by us
163+
delete $new_fs->{$root};
164+
}
165+
}
166+
}
141167
$notify[$idx]->reset;
142168
my $old_fs = +{ map { ($_ => $fs->{$_}) } keys %$new_fs };
143169
_compare_fs($old_fs, $new_fs, sub { push @events, { path => $_[0] } });
@@ -210,7 +236,7 @@ sub _full_scan {
210236

211237
# remove root entry
212238
# NOTE: On MSWin32, realpath and rel2abs disagree with path separator.
213-
delete $map{$fp}{File::Spec->rel2abs($fp)};
239+
delete $map{$fp}{File::Spec->rel2abs($fp)} if exists $map{$fp};
214240
}
215241

216242
return \%map;

0 commit comments

Comments
 (0)