Re: FVWM: Smart maximize
Hi, when trying to understand how to tweak/extend FVWM using Perl (FVWM::Module API), I found this request in the mailing list archives by chance. On Sat, 24 Nov 2012 04:28:02 -0800, Piotr Isajew wrote: > I wonder, if there is a command to do "smart maximize" in fvwm? > The command would move and resize current window to use the > largest free area of desktop, but not covering any other > windows. Is there something like this? As it looks like an interesting task (neither trivial nor overly complicated), I have given it a try. Although I'm not sure whether I'm using the API in an optimal way (unfortunately haven't been able to find many examples out there), I'm quite impressed how easy programming FVWM has become (if one likes using Perl). In order to test my solution put the attached perl script into your ModulePath, load it and define a key binding for it, e.g.: Key m WTSF 4 SendToModule smart_maximize.pl dummy It's probably far from perfect, but at least may serve as a starting point. #!/usr/bin/perl # Time-stamp: "2013-06-29 11:13:03 ah" # implement "smart maximize" as described in: # http://www.mail-archive.com/fvwm@lists.math.uh.edu/msg16809.html use warnings; use strict; use List::Util qw(min); use lib `fvwm-perllib dir`; use FVWM::Module; my $module = new FVWM::Module(Mask => M_STRING); my $pageTrackerWL = $module->track('WindowList'); my $vp_width = $pageTrackerWL->pageInfo->{vp_width}; my $vp_height = $pageTrackerWL->pageInfo->{vp_height}; $module->add_handler(M_STRING, \&smartMaximize); $module->event_loop; # main function smartMaximize gets called when issuing an FVWM command like: # SendToModule smart_maximize.pl dummy sub smartMaximize { my ($module, $event) = @_; # the window to be maximized my $own = $pageTrackerWL->data(${$event->args}{win_id}); # we want the window to actually grow my $minArea = $own->{width} * $own->{height} + min($own->{width}, $own->{height}); # Find all free rectangles in the current page where the window could be # displayed. This works as follows: # The list of display rectangles starts with one preliminary display # rectangle: the whole page. # Then one after another all windows are applied to the list of the # preliminary display rectangles. # If a window overlaps with a rectangle, it splits the rectangle into at # most four smaller rectangles: the one above the window, the one below it, # the one left of it, the one right of it. # Any rectangle not bigger than the window to be maximized gets discarded # at once. # After all windows have been applied to the rectangle list, the display # rectangles are not preliminary any longer, as they won't be split into # smaller rectangles any longer. # The biggest display rectangle will be used as the new window location. my @rectangles = (&createRectangle($own->{page_nx} * $vp_width, ($own->{page_nx} + 1) * $vp_width, $own->{page_ny} * $vp_height, ($own->{page_ny} + 1) * $vp_height)); # apply all windows to the display rectangle list foreach my $other ($pageTrackerWL->windows) { unless ($other->{win_id} == $own->{win_id} or $other->{desk} != $own->{desk}) { @rectangles = &applyWindow($other, $minArea, @rectangles); } } # take the rectangle with the largest area as destination my $dest; foreach my $rect (@rectangles) { if ($dest) { # first level criterion: bigger if ($rect->{area} > $dest->{area} # second level criterion: just as big, but more left or ($rect->{area} == $dest->{area} and ($rect->{x_min} < $dest->{x_min} # third level criterion: # just as big, just as left, but more up or ($rect->{x_min} == $dest->{x_min} and $rect->{y_min} < $dest->{y_min} { $dest = $rect; } } else { $dest = $rect; } } if ($dest) { # move the window to the display rectangle and let it fill it my $x = $dest->{x_min} - $own->{page_nx} * $vp_width; my $y = $dest->{y_min} - $own->{page_ny} * $vp_height; $module->send("WindowId $own->{win_id} Move ${x}p ${y}p Warp"); $module->send("WindowId $own->{win_id} Maximize grow grow"); } } # Apply a window to the current display rectangle list. # This may change the rectangle list. sub applyWindow { my ($other, $minArea, @oldRectangles) = @_; my $splitter = {x_min => $other->{page_nx} * $vp_width + $other->{x}, x_max => $other->{page_nx} * $vp_width + $other->{x} + $other->{width}, y_min => $other->{page_ny} * $vp_height + $other->{y}, y
Re: FVWM: Smart maximize
On 7 December 2012 12:15, Piotr Isajew wrote: > On Fri, Dec 07, 2012 at 08:35:21AM +, Thomas Adam wrote: > >> On 7 December 2012 07:32, Piotr Isajew wrote: >> > WindowId 0x%x ResizeMove %dp %dp %dp %dp >> >> I find it dubious you need to use the WindowID command here at all. > > Without WindowID being there I always got interactive selection > mode, when that command was executed. I meant more that there's other ways of specifying the window. I'd need to see this module to critique it properly though. -- Thomas Adam
Re: FVWM: Smart maximize
On 7 December 2012 07:32, Piotr Isajew wrote: > WindowId 0x%x ResizeMove %dp %dp %dp %dp I find it dubious you need to use the WindowID command here at all. > is there any way, besides of coding that logic into module, to > make this command operate in toggle mode, like Maximize does? ResizeMoveMaximize -- Thomas Adam
Re: FVWM: Smart maximize
On 2012-11-24, Piotr Isajew wrote: > On Sat, Nov 24, 2012 at 07:53:16AM -0500, Dan Espen wrote: > >> Key F2 A 4 Maximize grow grow > > Thanks, Dan. It's almost what I want. It expands the window using > all the available space based on it's current location. What I'm > looking for is a way to do the same, but in the largest available > area of the screen. So for complete solution I need also a way to > move that window to the largest free area of the screen before > that maximize. But it's a move forward anyway, so thanks once > again :) > This can be noise and this links in my TODO list so I don't read they yet but hope it will be useful (I collect it when search for tiling in Fvwm): https://github.com/urob/fvwm-tiling FvwmRearrange(1) http://dryice.name/blog/freebsd/tiling-window-management-with-fvwm/ http://noone.org/blog/English/Computer/X/How%20I%20use%20my%20virtual%20desktops.html https://github.com/rubykat/FvwmPiazza https://github.com/ThomasAdam/FvwmPiazza http://search.cpan.org/dist/FvwmPiazza/ https://metacpan.org/release/FvwmPiazza http://forums.gentoo.org/viewtopic-p-6664393.html -- Best regards!
Re: FVWM: Smart maximize
On 11/28/2012 10:17 AM, Bastian wrote: Have you tried to set the Style MinPlaceOverlap to subjected window and then call PlaceAgain on it? This works for me: DestroyFunc movetofreeplace AddToFunc movetofreeplace + I WindowStyle MinOverlapPlacement + I PlaceAgain First please do not top post (read the rules of the mailing list). The problem with this method is that it will find the first available free (or min overlap) region it can place the window. If there are multiple rectangles on the screen that are free of windows it will always pick the first one it finds (not the biggest rectangle). So though it was a suggestion to look at there is really no nice way I can see to mix it to be able to grow a window to fit in the biggest possible rectangle it can find. A FvwmPerl script will end up being the the best way I can think of to first find the biggest free rectangle and then to move/resize the window to fit in that rectangle. The hard part will be the problem of finding the biggest open rectangle (this is a logic/math problem). Once you have that it is fairly straight forward to move the window to that rectangle and maximize grow grow (or just resize it) to the right size. jaimos
Re: FVWM: Smart maximize
Jaimos Skriletz writes: > On Sat, Nov 24, 2012 at 02:55:47PM +0100, Piotr Isajew wrote: >> On Sat, Nov 24, 2012 at 08:37:03AM -0500, Dan Espen wrote: >> >> > I guess you are thinking of the largest free rectangular area. >> >> yes, that's right >> >> > I'm not aware of any such feature. >> >> I'll try to look for a solution myself. If I find something I'll >> post it to the list. > > The only thing similar I can think of is MinOverlapPlacement policy as > it does what you want (sort of). I cannot think of a simple way to mix > that placement policy (and replace your window) with trying to do this > smart maximization. But if you know a bit of C that is something you > can look up to see how it is done in terms of logic in determining the > bigest open rectangle. > > Just mentioning that placement policy because then you don't have to > rebuild the logic from nothing and you can use it as a starting place > to figuring out where the biggest rectangle is. I haven't looked at MinOverlap, but Google offers: http://stackoverflow.com/questions/7245/puzzle-find-largest-rectangle-maximal-rectangle-problem -- Dan Espen
Re: FVWM: Smart maximize
On Sat, Nov 24, 2012 at 02:55:47PM +0100, Piotr Isajew wrote: > On Sat, Nov 24, 2012 at 08:37:03AM -0500, Dan Espen wrote: > > > I guess you are thinking of the largest free rectangular area. > > yes, that's right > > > I'm not aware of any such feature. > > I'll try to look for a solution myself. If I find something I'll > post it to the list. The only thing similar I can think of is MinOverlapPlacement policy as it does what you want (sort of). I cannot think of a simple way to mix that placement policy (and replace your window) with trying to do this smart maximization. But if you know a bit of C that is something you can look up to see how it is done in terms of logic in determining the bigest open rectangle. Just mentioning that placement policy because then you don't have to rebuild the logic from nothing and you can use it as a starting place to figuring out where the biggest rectangle is. jaimos