#!/usr/bin/env perl # zenity.wrapper - Launcher for "zenity" main program # License: BSD-style [for this file only] # Revision: 080825 #--------------------------------------------------------------------- # overview #--------------------------------------------------------------------- # This script is a wrapper for the main Zenity executable [which must # be renamed to "zenity.bin"]. It tries to fix a Zenity/window-manager # problem. Specifically, the Zenity dialog box doesn't always appear # on the current desktop, and it doesn't always move to the front of # the window stack. The wrapper starts Zenity, waits briefly for the # dialog box to be created, and moves the dialog box to the appropri- # ate location [if possible]. # Note: This is a distro-specific script. It requires "wmctrl", which # isn't available everywhere. Additionally, some window managers # aren't "wmctrl"-compatible. # Requirements: # # a. "wmctrl" 1.07 or above. # # b. "wmctrl"-compatible window manager. # # c. Higher-level programs should specify unique "--title" strings # when they use "zenity". # # Note: If "--title" isn't specified, the wrapper will start # the main Zenity executable, regardless, but the move-forward # fix won't work. If "--title" is specified, but the string # used isn't unique, the move-forward fix may move multiple # windows forward. #--------------------------------------------------------------------- # module setup #--------------------------------------------------------------------- require 5.8.1; use strict; use Carp; use warnings; use Cwd; # Trap warnings $SIG {__WARN__} = sub { die @_; }; #--------------------------------------------------------------------- # basic constants #--------------------------------------------------------------------- use constant ZERO => 0; # Zero use constant ONE => 1; # One use constant TWO => 2; # Two use constant FALSE => 0; # Boolean FALSE use constant TRUE => 1; # Boolean TRUE #--------------------------------------------------------------------- # program parameters #--------------------------------------------------------------------- my $BASENAME = 'zenity'; # Program base name # Absolute path for package tree my $DIR_BASE = '__META_PREFIX__'; # Absolute path for renamed copy of # original executable my $TARGET_PROGRAM = "$DIR_BASE/bin/$BASENAME.bin"; #--------------------------------------------------------------------- # support routine[s] #--------------------------------------------------------------------- # This routine pauses very briefly. sub PauseVeryBriefly { select (undef, undef, undef, 0.05); } #--------------------------------------------------------------------- # This routine pauses for approx. 100 milliseconds. sub Pause100ms { select (undef, undef, undef, 0.10); } #--------------------------------------------------------------------- # main routine #--------------------------------------------------------------------- sub Main { my $output_wmctrl; # "wmctrl" output my $str; # Scratch my $title; # "--title" argument my @wid = (); # Window-ID list #--------------------------------------------------------------------- # Initial setup. select STDERR; $| = ONE; select STDOUT; $| = ONE; #--------------------------------------------------------------------- # Process the command line. for my $arg (@ARGV) { next unless $arg =~ m@^--title=(.+)\z@; $title = $1; $title =~ s@^\s+@@s; $title =~ s@\s+\z@@s; } #--------------------------------------------------------------------- # Start the target program. if (fork) { exec $TARGET_PROGRAM, @ARGV; } # If no title was specified, exit exit ZERO unless defined ($title) && length ($title); #--------------------------------------------------------------------- # Identify window-ID number[s] [if possible]. for my $ii (ONE..40) { &PauseVeryBriefly(); # Pause very briefly $str = `wmctrl -l 2>&1`; $str = "" if !defined $str; $output_wmctrl = $str; for my $line (split (/\s*\n\s*/, $output_wmctrl)) { next unless length $line; my ($x_wid, $x_title) = $line =~ m@^(0x[0-9a-f]+)\s+-?\d+\s+\S+\s+(\S.+)@; next unless defined $x_title; $x_title =~ s@\s+\z@@s; next unless $title eq $x_title; push (@wid, $x_wid); } last if scalar @wid; &Pause100ms(); # Pause 100ms } #--------------------------------------------------------------------- # Move window[s], if possible. for my $wid (@wid) # Process all matching windows { # Process next matching window &PauseVeryBriefly(); # Pause very briefly # Move window [and raise it] system "wmctrl -i -R $wid 2> /dev/null"; } undef; } #--------------------------------------------------------------------- # main program #--------------------------------------------------------------------- &Main(); # Call the main routine exit ZERO; # May or may not be reached