From 67eda26b6b490b6986a794a447afaa21ce0ea4b2 Mon Sep 17 00:00:00 2001 From: Joey Schulze Date: Wed, 11 Jun 2008 09:29:52 +0200 Subject: [PATCH 1/1] Graphical switch utility --- xswitch | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100755 xswitch diff --git a/xswitch b/xswitch new file mode 100755 index 0000000..e0ea8c7 --- /dev/null +++ b/xswitch @@ -0,0 +1,144 @@ +#! /usr/bin/perl + +# xswitch - Graphicsl switch utility +# Copyright (c) 2008 Joey Schulze +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + +use strict; +use warnings; + +use Getopt::Long; +use Config::IniFiles; +use Gtk2; + +my $config; +my $info = {}; +my $tooltips; +my $opt_config = $ENV{'HOME'} . '/etc/xswitch.conf'; + +sub config_read +{ + my $fname = shift; + + die "No configuration file found" unless -r $fname; + + my $cfg = new Config::IniFiles(-file => $fname); + + return $cfg; +} + +sub config_process +{ + my $fname; + + $info->{current} = ${$config->{sects}}[0]; +} + +sub next_state +{ + my $action = $config->val($info->{current}, 'action'); + + return $info->{current} unless defined $action; + + if ($action eq 'cycle') { + my $i; + for ($i=0;$info->{current} ne ${$config->{sects}}[$i] && $i<=$#{$config->{sects}};$i++) {}; + + if ($i == $#{$config->{sects}}) { + return ${$config->{sects}}[0]; + } else { + return ${$config->{sects}}[$i+1]; + } + } + return $info->{current}; +} + +sub window_update +{ + my $fname = $config->val($info->{current}, 'image'); + + if ($fname && defined(my $img = Gtk2::Image->new_from_file($fname))) { + $info->{button}->set_image($img); + $info->{button}->set_label(''); + } else { + $info->{button}->set_image(undef); + $info->{button}->set_label($info->{current}); + } + + my $tip = $config->val($info->{current}, 'tooltip'); + if ($tip) { + $tooltips->set_tip ($info->{button}, $tip); + } else { + $tooltips->set_tip ($info->{button}, ''); + } +} + +sub callback_command +{ + my $cmd = $config->val($info->{current}, 'command'); + + if (length $cmd) { + system("$cmd") == 0 or print STDERR "$cmd failed: $?\n"; + } + + my $next = next_state; + + if ($next ne $info->{current}) { + $info->{current} = $next; + window_update; + } +} + +sub mainwindow +{ + my $window = Gtk2::Window->new('popup'); + + $tooltips = new Gtk2::Tooltips; + $tooltips->enable; + + $window->set_title('X-Switch'); + $window->set_gravity('south-east'); + $window->signal_connect('destroy' => sub { Gtk2->main_quit }); + + $info->{button} = Gtk2::Button->new(); + $info->{button}->signal_connect('clicked' => \&callback_command); + $info->{button}->set_border_width(0); + + window_update; + + $window->add($info->{button}); + $window->show_all; +} + +sub usage +{ + print "xswitch [--help] [--config cfg]\n"; + print "Provide a popup window for cycling actions\n"; + print "e.g. for switching between keyboard layouts\n"; + exit(0); +} + +GetOptions('config=s' => \$opt_config, + 'help' => \&usage); + +$config = config_read $opt_config; +config_process; + +init Gtk2; + +mainwindow; + +Gtk2->main; -- 2.20.1