aboutsummaryrefslogtreecommitdiff
path: root/ratpoison/workspace
diff options
context:
space:
mode:
Diffstat (limited to 'ratpoison/workspace')
-rwxr-xr-xratpoison/workspace298
1 files changed, 298 insertions, 0 deletions
diff --git a/ratpoison/workspace b/ratpoison/workspace
new file mode 100755
index 0000000..c314d0a
--- /dev/null
+++ b/ratpoison/workspace
@@ -0,0 +1,298 @@
+#!/usr/bin/env perl
+#
+# Copyright (c) 2006 Daniel M. Webb
+# Copyright (c) 2005 Mike O'Connor
+# All rights reserved.
+# Author Daniel M. Webb <public@danielwebb.us>
+# Original Author Mike O'Connor <stew@vireo.org>
+#
+# Modified by Shawn Betts.
+#
+# code was adapeted from rpws that comes from ratpoison containing the follwing copyright:
+# Copyright (C) 2003 Shawn Betts
+# Author: Shawn Betts
+#
+use strict;
+use Fcntl qw (:flock);
+use Getopt::Std;
+
+my $ratpoison = $ENV{ "RATPOISON" } || "ratpoison";
+my $tmp=$ENV{ "TMP" } || "/tmp";
+my $lockfile = $ENV{ "WORKSPACE_LOCKFILE" } || "$tmp/workspace.$<.lock";
+
+my $number_of_workspaces = 1;
+my @ws_names;
+my @ws_toggle_memory_trigger;
+$ws_names[0] = "default"; # workspace 0 can't be renamed due to bug
+for( my $i = 1; $i <= 13; $i++ )
+{
+ $ws_names[$i] = "workspace$i";
+ $ws_toggle_memory_trigger[$i] = "true";
+}
+
+# Load configuration now that defaults are set
+require "$ENV{HOME}/.ratpoison/workspace.conf";
+set_workspaces(\$number_of_workspaces, \@ws_names, \@ws_toggle_memory_trigger);
+
+sub help
+{
+ system("pod2usage", $0);
+ print( "for more detailed documentation run \"perldoc $0\"\n" );
+}
+
+sub rp_call
+{
+ my $result = `$ratpoison -c "@_"`;
+ chomp( $result );
+ chomp( $result );
+ return $result;
+}
+
+sub ws_init_ws
+{
+ my $num = shift;
+
+ if ($num > 0)
+ {
+ rp_call( "gnew $ws_names[$num]" );
+ }
+ my $fd = fdump();
+ rp_call( "setenv fspl$num $fd" );
+}
+
+sub fdump
+{
+ return rp_call( "fdump" );
+}
+
+sub ws_init
+{
+ my $num = shift;
+
+ # Backup the frames
+ my $fd = fdump();
+
+ rp_call( "select -" );
+ rp_call( "only" );
+
+ my $i;
+ for( my $i = 0; $i < $number_of_workspaces; $i++ )
+ {
+ ws_init_ws( $i );
+ rp_call( "setenv toggle_memory$i 0" );
+ }
+ # Rename group 0 now that there are other groups
+ # (it can't be deleted if it already exists)
+ #rp_call( "gdelete 0" );
+ #rp_call( "gnew $ws_names[0]" );
+ # NOTE: group 0 apparently can't be deleted even if empty, so can't be renamed.
+
+ # Start in workspace 0.
+ $fd = fdump();
+ rp_call( "gselect default" );
+ rp_call( "setenv fspl0 $fd" );
+ rp_call( "setenv cur_workspace 0" );
+
+ # restore the frames
+ rp_call( "frestore $fd" );
+
+ if( -e "$lockfile" )
+ {
+ unlink ("$lockfile" );
+ }
+}
+
+sub ws_save_frames
+{
+ my $ws = rp_call( "getenv cur_workspace" );
+ my $fd = fdump();
+ rp_call( "setenv fspl$ws $fd" );
+}
+
+sub ws_restore
+{
+ my $new_ws = shift;
+ my $cur_ws = rp_call( "getenv cur_workspace" );
+ # For togglers, give a warning if same ws is chosen.
+ # For non-togglers, selecting same ws toggles back
+ if ($new_ws == $cur_ws and $ws_toggle_memory_trigger[$cur_ws] eq "true")
+ {
+# rp_call( "echo Already on workspace $new_ws" );
+ }
+ else
+ {
+ if ($new_ws == $cur_ws)
+ {
+ # Special case of choosing non-toggler goes back to previous
+ $new_ws = rp_call( "getenv toggle_memory$cur_ws" );
+ }
+ ws_save_frames();
+ if ($ws_toggle_memory_trigger[$cur_ws] eq "true")
+ {
+ rp_call( "setenv toggle_memory$new_ws $cur_ws" );
+ }
+ `killall xbindkeys`;
+ my $rc_dir = `dirname $0`; chomp($rc_dir);
+ my $rcfilename="$rc_dir/macro/xbindkeysrc/" . "xbindkeysrc.$ws_names[$new_ws]";
+ if (-f $rcfilename) {
+ print "running xbindkeys -f $rcfilename\n";
+ `xbindkeys -f $rcfilename`;
+ }
+ rp_call( "gselect $ws_names[$new_ws]");
+ my $last = rp_call( "getenv fspl$new_ws" );
+ rp_call( "frestore $last" );
+ rp_call( "setenv cur_workspace $new_ws" );
+ # Get window number/name too
+ my $window_info=rp_call("info");
+ my $window_number = $window_info;
+ $window_number =~ s/^\(.*?\) (\d+).*$/$1/;
+ my $window_name = $window_info;
+ $window_name =~ s/^\(.*?\) \d+\((.*)\)$/$1/;
+# rp_call( "echo Workspace: $ws_names[$new_ws]\nWindow : $window_number - $window_name" );
+ }
+}
+
+sub ws_toggle
+{
+ my $cur_ws = rp_call( "getenv cur_workspace" );
+ my $new_ws = rp_call( "getenv toggle_memory$cur_ws" );
+ ws_restore($new_ws);
+}
+
+# unfinished:
+sub list_all_windows
+{
+ my $cur_ws = rp_call( "getenv cur_workspace" );
+ print("ratmenu -style dreary -fg '#657b83' -bg '#eee8d5'");
+ # FIXME: 6 should be replaced with actual number of workspaces
+ foreach my $i (0..6)
+ {
+ rp_call( "gselect $ws_names[$i]");
+ my $result = `$ratpoison -c "windows %n %t"`;
+ foreach my $line (split (/\n/, $result))
+ {
+ my @window = split(/ /, $line);
+ print(" \"$ws_names[$i] : $line\" \"$0 $i; ratpoison -c \\\"select $window[0]\\\" \"");
+ }
+ }
+ ws_restore($cur_ws);
+}
+
+sub add_aliases
+{
+ foreach my $i (0..$number_of_workspaces-1) {
+ rp_call ( "alias workspace$i exec $0 $i" );
+ }
+ rp_call ( "alias workspace_toggle exec $0 toggle" );
+ rp_call ( "alias rpwsn exec $0 next" );
+ rp_call ( "alias rpwsp exec $0 prev" );
+ rp_call ( "alias rpwsmn exec $0 movenext" );
+ rp_call ( "alias rpwsmp exec $0 moveprev" );
+
+}
+
+sub add_keys
+{
+ foreach my $i (0..$number_of_workspaces-1) {
+ rp_call ( "bind C-$i workspace$i" );
+ }
+ rp_call ( "bind C-g workspace_toggle" );
+}
+
+my $arg = shift @ARGV;
+
+if( $arg eq "help" ) {
+ help();
+} elsif( $arg eq "init" ) {
+ my %opts;
+ ws_init();
+ getopts('ka', \%opts);
+ add_aliases() if $opts{'a'} || $opts{'k'};
+ add_keys() if $opts{'k'};
+} else {
+ open LOCK, ">>$lockfile" or die "Cannot open lockfile: $lockfile";
+ flock(LOCK, LOCK_EX);
+ if ( $arg eq "toggle" ) {
+ ws_toggle();
+ } elsif ( $arg eq "list_all" ) {
+ list_all_windows();
+ } elsif ( $arg eq "current" ) {
+ my $cws = rp_call( "getenv cur_workspace" );
+ print "$cws";
+ } elsif ($arg >= 0 and $arg <= 13) {
+ ws_restore( $arg );
+ } else {
+ help();
+ }
+}
+
+__END__
+
+=head1 NAME
+
+workspace - Implements multiple workspaces in ratpoison
+
+=head1 SYNOPSIS
+
+ workspace init [-k] [-a] - setup workspace with $number_of_workspaces workspaces
+ ($number_of_workspaces is set in the workspace.conf file).
+ -a sets up command aliases;
+ -k sets up key bindings and aliases.
+ workspace help - this documentation
+ workspace n - switch to this workspace
+ workspace toggle - switch to previous workspace (other than default)
+ workspace toggle_default - switch back and forth to between default workspace
+ workspace current - print the index of the current workspace
+
+
+=head1 DESCRIPTION
+
+ B<workspace> implements multiple workspaces in ratpoison by making calls
+ to fdump, freestore. It was adapted from rpws which comes with
+ ratpoison in the contrib directory.
+
+=head1 USAGE
+
+Add the following line in ~/.ratpoisonrc
+
+ exec /path/to/workspace init -k
+
+This creates 6 aliases workspace1, workspace2, etc. It also binds the keys C-1,
+C-2, etc to each workspaceN alias. Workspace names can be configured at the
+top of this script.
+
+The toggle command is analogous to the ratpoison "other" command for windows,
+except it is for workspaces and is implemented in this script instead of within
+ratpoison.
+
+If $ws_toggle_memory_trigger is true for a workspace, that workspace sets
+the toggle memory on return. If it's false, it will just toggle back to the
+previous workspace but the memory will stay the same.
+
+If there is a file /path/to/workspace/macro/xbindkeysrc/xbindkeysrc.<workspace N name>,
+then xbindkeys will be run with this file as configuration.
+
+=head1 FILES
+
+ workspace requires use of a lockfile. It defaults to using
+/tmp/workspace.<UID>.lock but this can be changed by setting the
+environment variable WORKSPACE_LOCKFILE to your desired lockfile.
+
+=head1 AUTHOR
+
+ Mike O'Connor <stew@vireo.org>
+
+=head1 COPYRIGHT
+
+ Copyright (c) 2005 Mike O'Connor
+ All rights reserved.
+
+ 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.