Skip to content

Instantly share code, notes, and snippets.

@dru8274
Last active Apr 1, 2016
Embed
What would you like to do?
WallBrowser
## Lines from my main config
## Border color for the thumbs in the WallBrowser Menu
InfoStoreAdd wallthumbs_color "SteelBlue4"
## Path to the wallpapers folder
InfoStoreAdd wallpapers_folder "$[FVWM_USERDIR]/wallpapers"
## The WallBrowser module also expects folder ~/.fvwm/.wallthumbs to exist
DestroyMenu MenuRoot
AddToMenu MenuRoot
+ DynamicPopupAction MakeMenuRoot
DestroyFunc MakeMenuRoot
AddToFunc MakeMenuRoot
+ I SetScrotFilepath
+ I DestroyMenu recreate MenuRoot
+ I AddToMenu MenuRoot MissingSubmenuFunction WallBrowser
+ I AddToMenu MenuRoot MenuRoot Title
+ I AddToMenu MenuRoot "%mm_urxvt.png%&Console" StartFvwmConsole 64x35
+ I AddToMenu MenuRoot "%mm_identify.png%&Identify" Pick Module FvwmIdent
#+ I AddToMenu MenuRoot "Fvwm&Talk" Module FvwmForm FvwmForm-Talk
+ I AddToMenu MenuRoot "%mm_xerrors.png%&Xerrors" \
RunInUrxvt 49x27 Xerrors tail -f $[HOME]/.xsession-errors
+ I AddToMenu MenuRoot "" Nop
+ I AddToMenu MenuRoot "%mm_scrot.png%&Scrot >" \
Popup ScrotMenu
+ I AddToMenu MenuRoot "%mm_images.png%&Walls >" \
Popup "$[infostore.wallpapers_folder]"
+ I AddToMenu MenuRoot "%system_menu.png%&Modules >" Nop
+ I AddToMenu MenuRoot "" Nop
+ I AddToMenu MenuRoot "%mm_application-exit.png%&Destroy" Pick Destroy
#+ I AddToMenu MenuRoot "%mm_config.png%&Config >" \
# Popup ConfigMenu
## Using the WallBrowser module to make the thumbnail menu
DestroyFunc WallBrowser
AddToFunc WallBrowser I ModuleSynchronous \
WallBrowser "$[infostore.wallthumbs_color]" "$[0]"
#---------------------------#
# WALLPAPER MENUSTYLES #
#---------------------------#
CopyMenuStyle * WallpaperMenuStyle
MenuStyle WallpaperMenuStyle VerticalMargins 7 7
MenuStyle WallpaperMenuStyle VerticalItemSpacing 30 30
#!/usr/bin/perl
## I tried to rewrite this using ->event_loop and ->terminate, to query
## FVWM's configuration database to obtain its settings and vars. But
## it confounded me. It seems that commands were sent to FVWM, but only
## processed by FVWM after the initial wallpaper menu was exited. If
## this module was not part of a MissingSubmenuFunction menu, I doubt
## this problem would occur. So I have now resolved to not obtain this
## module'ssettings from the configuration database.
use utf8 ;
use strict ;
use warnings ;
use v5.20 ;
use lib `fvwm-perllib dir`;
use FVWM::Module;
use Image::Magick ;
#use Data::Dump qw( dump ) ;
my $module = new FVWM::Module(
Name => 'WallBrowser',
Debug => 0,
);
## Read in the current folder for this dynamic menu
my $dir = pop ;
## Color for border around thumbnail.
#my $wallthumb_border_color = "SteelBlue4" ;
#$module->showMessage("wall_bdr_color: $wallthumb_border_color") ;
my $wallthumb_border_color = pop ;
## Folder in which to store wallpaper thumbnails.
my $thumbdir = "$ENV{FVWM_USERDIR}/.wallthumbs" ;
## Menu icon for folder entries in the menu.
my $icon_dir = "$ENV{HOME}/.icons/AwOken/clear/24x24/places/awoken/awokenclear/folder-photos.png" ;
## Long menu labels get truncated. Maximum length for labels in chars.
my $charmax = 25 ;
## Fvwm menustyle name for this menu.
my $menustyle = "WallpaperMenuStyle" ;
## Cmnd string used to generate the folder menu.
my $menucmd = 'fvwm-menu-directory --icon-file __PIXMAP__ ' ;
$menucmd .= "--icon-dir \"$icon_dir\" --links --dir \"$dir\" " ;
$menucmd .= '--command-file="Module FvwmWallpaper \"%f\"" ' ;
$menucmd .= '--func-name WallBrowser ' ;
## Magick properties to create a nice thumbnail.
my $wallthumb_geom = "80x40!" ;
my $wallthumb_border_width = 4 ;
## my $wallthumb_pad_color = "grey9" ;
## my $wallthumb_pad_geom = "x4" ;
my $quality = 99 ;
## Create thumbs for all images in the current folder.
foreach my $wall (glob("$dir/*.{png,jpg}")) {
## generate a filename for the thumbnail.
my $thumb = $wall ;
$thumb =~ s/^.*\/// ;
$thumb =~ s/[.]\w\w\w$/.png/ ;
$thumb = "$thumbdir/$thumb" ;
## Goto next wally if a good thumb already exists.
if (-e $thumb) {
my @wallstat = stat($wall) ;
my @thumbstat = stat($thumb) ;
next if $wallstat[9] <= $thumbstat[9] ;
unlink $thumb ;
}
## Create a new thumb.
thumbificate($wall, $thumb) ;
say STDERR "WallThumb : $thumb" ;
}
foreach my $line (`$menucmd`) {
chomp $line ;
## Discarding unwanted menu entries
if ($line =~ /Nop$/ or $line =~ /Exec cd/) {
next
## Add a title to the menu.
} elsif ($line =~ /^AddToMenu\s+(\S+)/) {
#my $menuname = $1 ;
#$module->showMessage("debugX: $1") ;
## my $title = $line ;
## $title =~ s/^.*\/// ;
## $title =~ s/\"//g ;
## my $out = "$line \"Walls\" Title " ;
#sendcmd($out) ;
sendcmd($line) ;
sendcmd("ChangeMenuStyle $menustyle $1") ;
## For each wallpaper entry, substitite in a thumbicon.
} elsif ($line =~ /^.*__PIXMAP__%([^"]*)([.]\w\w\w)["](.*)$/) {
## Shorten the menu label if too long.
my $name = "" ;
my $num = $charmax - 5 ;
if (length($1) > $num) {
$name = substr $1, 0, $num ;
$name .= "-$2" ;
} else {
$name = "$1$2" ;
}
## Make menu entry with thumbicon, and send to fvwm.
#my $out = '+ "%' . "$thumbdir/$1.png%$name\"$3" ;
my $out = '+ "%' . "$thumbdir/$1.png%\"$3" ;
sendcmd($out) ;
## Add a ">" to all folder entries.
} elsif ($line =~ /^(.*\"%\/[^"]+)(\"\sPopup.*)$/) {
sendcmd("$1\t>$2") ;
} else {
sendcmd($line) ;
}
}
exit ;
#### SUBROUTINES
sub thumbificate {
my $wall = shift ;
my $thumb = shift ;
## Abort thumb if magick cannot read the wallpaper.
my $err = 1 ;
return 0 if not open(WALL, $wall) ;
my $image = Image::Magick->New(quality => $quality) ;
$err = $image->Read(file=>\*WALL) ;
close(WALL) ;
return 0 if $err ;
## Create thumbnail
return 0 if $image->Thumbnail(
geometry => $wallthumb_geom,
) ;
## Add a colored border to the thumb
return 0 if $image->Border(
width => $wallthumb_border_width,
height => $wallthumb_border_width,
bordercolor => $wallthumb_border_color,
) ;
## ## Add another border to top and bottoms sides,
## ## but using the menus background color.
## return 0 if $image->Border(
## bordercolor => $wallthumb_pad_color,
## geometry => $wallthumb_pad_geom,
## ) ;
## Save the thumb into its storage folder.
$err = 1 ;
open(THUMB, ">$thumb") ;
$err = $image->Write(
file => \*THUMB,
filename => $thumb,
quality => $quality,
) ;
close THUMB ;
if ($err) { return 0 } else { return 1 } ;
}
sub sendcmd {
foreach (@_) {
$module->send($_) ;
#$module->showMessage("debug: $_") ;
}
}
#### WallBrowser
How I did the Graphs at the top right of this screenshot : http://i.imgur.com/RKC2K1O.png?1
Other fvwm configs have similar wallpaper menus like this, although mine might be prettier.
I started by looking in the fvwm-nightshade config, specifically his WallpaperBrowser
function, which he credits to someone called taviso. But looking at that functions huge piperead
command, I decided to reimplement it a an fvwmperl module, and use imagemagick to improve the
wallpaper thumbnails.
Wallpaper menus like this use the fvwm-menu-directory command which has its own manpage, and
the MissingSubmenuFunction menu option. There are basic examples for MissingSubmenuFunction in
the fvwm manpage and the fvwm-menu-directory manpage. It dynamically creates fvwm menus
based on some directory structure, with the assistance of a helper function.
Files below
1] Lines from my main config.
2] WallBrowser, fvwmperl module
## On Debian, tells you which perl lib to install to provide a certain perl module
http://deb.perl.it/debian/cpan-deb/
#### MORE INFO ABOUT FVWMPERL MODULES
## Read the hidden fvwmperl manpages
$ fvwm-perllib man index
## A folder full of simple fvwmperl examples
ftp://ftp.fvwm.org/pub/fvwm/devel/sources/tests/perl/
## An excellent fvwmperl module example
http://www.fvwmforums.org/phpBB3/viewtopic.php?f=38&t=3069&hilit=fvwmsleep
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment