gnu.app.puppet
Class Puppet

java.lang.Object
  extended by gnu.app.Application
      extended by gnu.x11.Application
          extended by gnu.app.puppet.Puppet

public class Puppet
extends Application

Window manager.

In my PC 104 keyboard system,

   META (MOD1) = "alt" next to spacebar 
   ALT (MOD4) = "window" next to meta
   SUPER (MOD3) = "menu" next to right CONTROL
 
Please see Xmodmap.

Bindings

KEY SEQUENCECOMMAND
basic
[enter]finish
[kp-enter]finish
[escape]finish or abort-switch-focus
[(control delete) (meta DIGIT)] lanuch-command DIGIT
[(control delete) S]*search-window-backward
[(control delete) s]*search-window-forward
focus
[(meta tab)]switch-focus-ignore-class-forward
[(shift meta tab)] switch-focus-ignore-class-backward
[(alt tab)]switch-focus-same-class-forward
[(shift alt tab)] switch-focus-same-class-backward
[(super tab)] switch-focus-different-class-forward
[(super tab)] switch-focus-different-class-backward
window
[(control delete) ARROW]*move
[(control delete) (shift ARROW)]*move faster
[(control delete) (control ARROW)]*resize
[(control delete) (control ARROW)] *resize faster
[(control delete) pageup]raise
[(control delete) page-down]lower
[(control delete) d]!dump-info
[(control delete) f]toggle-focus
[(control delete) F]grant-all-focus
[(control delete) h]!hide-which
[(control delete) H]!unhide-which
[(control delete) m]minimize
[(control delete) M]!maximize
[(control delete) r]restore-size
[(control delete) R]save-size
[(control delete) w]!warp-pointer
[(control delete) z]*relocate
register
[(control delete) space KEY] client-to-register KEY
[(control delete) j KEY]jump-to-register KEY
[(control delete) (control DIGIT)] jump-to-register DIGIT
critical
[(control delete) backspace d]delete-window
[(control delete) backspace k]kill-window
[(control delete) backspace Q]quit-puppet
geometry
[(control delete) g ARROW]*gravitate
[(control delete) g (shift ARROW)] *gravitate-absolute
[(control delete) g ?2]*scale-two-third
[(control delete) g ?3]*scale-one-and-half
[(control delete) g ?d]*scale-double
[(control delete) g ?h]*scale-half
mouse
[(meta BUTTON) on root]lanuch-on-root
[BUTTON on root]pointer-root-focus
[(control button1)]focus-with-raise
[(control button2)]focus-without-raise
[(control button3)]lower-behind
[(control meta button1)]delete-window
[(control meta button3)]kill-window
mouse key
[(control delete) KP_ARROW]*move-pointer
[(control delete) (shift KP_ARROW)] *move-pointer faster
[(control delete) (control shift KP_ARROW)] *move-pointer even faster
[(control delete) kp-begin]click-button1
[(control delete) (shift kp-begin)] double-click-button1
[(control delete) kp-divide]click-button1
[(control delete) (shift kp-divide)] double-click-button2
[(control delete) kp-multiply]click-button1
[(control delete) (shift kp-multiply)] double-click-button3
*
persistent command
!
command accepting argument
ARROW
up, down, left, or right
BUTTON
BUTTON1, BUTTON2, BUTTON3
DIGIT
0, 1, 2, 3, 4, 5, 6, 7, 8, or 9
KEY
any key (including modifier)
KP_ARROW
kb_up, kb_down, kb_left, kb_right, kb_home, kb_end, kb_pageup, kb_pagedown

Persistent Command

There are two types of commands: persistent commands, and non-persistent commands. Non-persistent commands such as `delete-window' will exit active keyboard state (ungrab keyboard) when their actions are executed. On the other hand, persistent commands such as `relocate' will stay in active keyboard state (do not ungrab keyboard) even when their actions are executed. This feature allows users execute similar commands in a sequence without repeatively pressing the system key.

Note, however, there is no visual feedback for persistent commands. Users may feel their keyboards are locked, while actually this window manager is expecting more keystrokes. Remember to press `finish' key to finish a persistent command.

Argument

A prefix argument mechanism similar to that in Emacs is employed as follows. After pressing system key and before pressing the command key, pressing any digit (or '-' for negative) will become the argument for the command. There can be more than one digits, which will be formed as an integer argument in decimal.
COMMANDARGUMENTDESCRIPTION
dump-infonothingdump-basic-info
negativedump-hidden-windows
otherdump-all-windows
hide-whichnothinghide-focus
negativehide-others
otherhide-same-class
unhide-whichnothingundo-hide
negativeunhide-all
otherunhide-same-class
maximizenothingmaximize-user-space
othermaximize-full-screen

Customization

There aren't much to customized about! In fact, you have to edit Java source code and recompile to customize anything at all. Check gnu/app/puppet/Preference.java and key_process_*() in gnu/app/puppet/Puppet.java.

Focus Policy - Keyboard

Basic switch-focus ([(meta tab)] and [(meta shift tab)]) (similar to Microsoft Windows (tm)): to change focus to the most recently used normal window, press [(meta tab)]; to change focus to the least recently used normal window, press [(meta shift tab)]. To navigate all normal windows, continuously press and release TAB while holding META. Normal windows are those in state NORMAL which is the default state for freshly mapped windows. Windows that are hidden or denied focus by user, or unmapped by application are not considered normal.

Class-based switch-focus ([(alt tab)] and [(super tab)]): they are exactly the same as [(meta tab)] counterparts, except that the selection criteria are WM-CLASS sensitive. WM-CLASS is an classification of applications defined in icccm 4.1.2.5. While [(alt tab)] considers all normal windows, WINDOW-TAB considers normal windows that are of the same WM_CLASS as the window under current focus; and [(super tab)] considers those of different WM_CLASS. Note pressing SHIFT will reverse the direction.

Find Window (`search-window-forward' and `search-window-backward'): you can search and focus a window by pressing its first character of its WM-CLASS string. To go to next matching window, press the same character again, for as many times as you want. Press [enter] or [escape] when done (as it is a persistent command). To search among all managed windows (including normal, hidden and focus-denied windows), hold SHIFT while pressing the character, that is, press its corresponding capital letter.

Register (`client-to-register' and `jump-to-register') (similar to Emacs buffer register): you can store a window to a register, and then later restore the focus to that window in the register. A register is any key (including control, alt, shift....!) on the keyboard. `client-to-register stores a window to a register, while `jump-to-register' later will unhide and raise (if necessary) the window in the register, and then give it the input focus.

Fall-back: this policy decides which window to focus if the current window is being hidden, unmapped, or denied focus. Unlike Microsoft Windows (tm) which unhelpfully gives the focus back to nowhere, focus will be fallen back to the most recently used normal window (as if [(meta tab)] is pressed).

Focus Policy - Mouse

A policy similar to CLICK-TO-FOCUS in other window managers is employed as follows. To raise and focus a window, press BUTTON1 while holding CONTROL; to focus without raising, press BUTTON2 while holding CONTROL; to lower and window and give focus to some other window (happens to contain the pointer after re-stacking), press BUTTON3 while holding CONTROL.

Intercepting button press events is discouraged (prohibited?) in icccm, but there is not much choice as we don't do re-parenting.

Mouse Key

A simple mechanism is employed to support moving the pointer with keyboard. Please check the above section, "Binding", for details.

Supposedly, X server comes with XKB extension that supports MouseKey as a built-in feature. However, personally I find it inconvenient to use (num-lock for on/off and default click keys) and not highly customizable (acceleration time and delay). Moreover, there is a serious bug in reference implementations of X server as pointed out by Stephen Montgomery-Smith (stephen@math.missouri.edu) here. He also wrote some customization tool ( Xkkset) for many XKB features. In the meantime, Puppet supports its own mouse key binding as a supplementary mechanism.

See Also:
screenshot, help output

Field Summary
 boolean alt_down
           
 int argument
           
 boolean argument_negative
           
 boolean argument_present
           
 java.util.Vector clients
          A list of all managed children of root window, that is, our clients.
 boolean control_down
           
static int DELTA_LARGE
           
static int DELTA_SMALL
           
 Client focus
           
 Client focus_base
          The active window when FOCUS-KEY (ALT-TAB, WINDOW-TAB, or MENU-TAB) is pressed.
 boolean focus_key_pressed
           
 java.util.Vector focus_so_far
           
static int HIDDEN
           
 int keycode
           
 int keysym
           
 Client last_hide
           
 boolean meta_down
           
static int NO_FOCUS
           
static int NORMAL
           
 Preference pref
           
 int prefix0
           
 int prefix1
           
 boolean print_event
           
static java.util.Random random
           
 Client[] registers
          see Focus Policy - Keyboard.
 Window root
           
 boolean shift_down
           
 Rectangle space
           
 boolean super_down
           
static int SWITCH_KEYSYM
           
 boolean system_key_pressed
           
static int SYSTEM_KEYSYM
           
static int SYSTEM_MODIFIER
           
static int UNMANAGED
           
 XTest xtest
           
 
Fields inherited from class gnu.x11.Application
display
 
Constructor Summary
Puppet(java.lang.String[] args)
           
 
Method Summary
 void alert_user(java.lang.String message)
           
 void client_to_register(Client client, int keycode)
           
 void control_root_window()
           
 void deny_focus(Client client)
           
 void focus_client_first_char(Client client, boolean reverse, char c, boolean all)
           
 void give_up_focus(Client client)
           
 void grab_keybut()
           
 void grant_all_focus()
           
 void grant_focus(Client client)
           
 boolean grant_preference(Client client)
           
 void hide_others(Client client)
           
 void hide_same_class(Client client)
           
 void hide(Client client)
           
 void jump_to_register(int keycode)
           
 void key_click_button(int button)
           
 boolean key_do_change_geometry()
           
 boolean key_do_critical_operation()
           
 boolean key_do_jump_lanuch_or_argument()
           
 void key_dump_info()
           
 void key_hide_which()
           
 void key_move_or_resize(int x_direction, int y_direction)
           
 void key_move_pointer(int x_direction, int y_direction)
           
 boolean key_process_no_prefix()
           
 boolean key_process_prefix0()
           
 boolean key_process_prefix1()
           
 boolean key_process()
           
 void key_search_client()
           
 void key_switch_focus()
           
 void key_unhide_which()
           
 void key_warp_pointer()
           
static void main(java.lang.String[] args)
           
 void manage(Client client)
           
 void maximize(Client client, boolean full_screen)
           
 void minimize(Client client)
           
 Client next_client_different_class(Client from, boolean reverse)
           
 Client next_client_first_char(Client from, boolean reverse, char c, boolean all)
           
 Client next_client_normal(Client from, boolean reverse)
           
 Client next_client_same_class(Client from, boolean reverse)
           
 Client next_client(Client from, boolean reverse)
           
 void read_and_dispatch_event()
           
 void register_fall_back(Client client)
           
 void relocate(Client client)
           
 void restore_size(Client client)
           
 void save_size(Client client)
           
 void scale_size(Client client, double factor)
           
 void scan_children()
           
 void set_focus(Client client, boolean warp_pointer)
           
 void toggle_focus(Client client)
           
 void unhide_all()
           
 void unhide_same_class(Client client)
           
 void unhide(Client client)
           
 void update_client_order(Client client)
           
 void when_button_press(ButtonPress event)
           
 void when_client_message(ClientMessage event)
           
 void when_configure_request(ConfigureRequest event)
           
 void when_destroy_notify(DestroyNotify event)
           
 void when_key_press(KeyPress event)
           
 void when_key_release(KeyRelease event)
          Handle *-TAB key release.
 void when_map_notify(MapNotify event)
           
 void when_map_request(MapRequest event)
           
 void when_property_notify(PropertyNotify event)
           
 void when_quit()
           
 void when_unmap_notify(UnmapNotify event)
           
 void when(Event event)
           
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

SYSTEM_MODIFIER

public static final int SYSTEM_MODIFIER
See Also:
Constant Field Values

SYSTEM_KEYSYM

public static final int SYSTEM_KEYSYM
See Also:
Constant Field Values

SWITCH_KEYSYM

public static final int SWITCH_KEYSYM
See Also:
Constant Field Values

UNMANAGED

public static final int UNMANAGED
See Also:
Constant Field Values

NORMAL

public static final int NORMAL
See Also:
Constant Field Values

HIDDEN

public static final int HIDDEN
See Also:
Constant Field Values

NO_FOCUS

public static final int NO_FOCUS
See Also:
Constant Field Values

DELTA_LARGE

public static final int DELTA_LARGE
See Also:
Constant Field Values

DELTA_SMALL

public static final int DELTA_SMALL
See Also:
Constant Field Values

registers

public Client[] registers
see Focus Policy - Keyboard.


clients

public java.util.Vector clients
A list of all managed children of root window, that is, our clients. We need to frequently remove and add elements to maintain focus order - any better/faster data structure?

See Also:
scan_children()

focus_base

public Client focus_base
The active window when FOCUS-KEY (ALT-TAB, WINDOW-TAB, or MENU-TAB) is pressed. Used to aid prevent looping and maintain focus order.

See Also:
next_client(Client, boolean)

focus_so_far

public java.util.Vector focus_so_far

pref

public Preference pref

space

public Rectangle space

root

public Window root

focus

public Client focus

last_hide

public Client last_hide

xtest

public XTest xtest

print_event

public boolean print_event

system_key_pressed

public boolean system_key_pressed

focus_key_pressed

public boolean focus_key_pressed

random

public static final java.util.Random random

keycode

public int keycode

keysym

public int keysym

alt_down

public boolean alt_down

control_down

public boolean control_down

meta_down

public boolean meta_down

shift_down

public boolean shift_down

super_down

public boolean super_down

prefix0

public int prefix0

prefix1

public int prefix1

argument

public int argument

argument_present

public boolean argument_present

argument_negative

public boolean argument_negative
Constructor Detail

Puppet

public Puppet(java.lang.String[] args)
       throws NotFoundException
Throws:
NotFoundException
Method Detail

alert_user

public void alert_user(java.lang.String message)

client_to_register

public void client_to_register(Client client,
                               int keycode)

control_root_window

public void control_root_window()

deny_focus

public void deny_focus(Client client)

focus_client_first_char

public void focus_client_first_char(Client client,
                                    boolean reverse,
                                    char c,
                                    boolean all)

give_up_focus

public void give_up_focus(Client client)

grab_keybut

public void grab_keybut()

grant_all_focus

public void grant_all_focus()

grant_focus

public void grant_focus(Client client)

grant_preference

public boolean grant_preference(Client client)

hide

public void hide(Client client)

hide_others

public void hide_others(Client client)

hide_same_class

public void hide_same_class(Client client)

jump_to_register

public void jump_to_register(int keycode)

key_do_change_geometry

public boolean key_do_change_geometry()

key_do_critical_operation

public boolean key_do_critical_operation()

key_do_jump_lanuch_or_argument

public boolean key_do_jump_lanuch_or_argument()

key_dump_info

public void key_dump_info()

key_hide_which

public void key_hide_which()

key_unhide_which

public void key_unhide_which()

key_move_or_resize

public void key_move_or_resize(int x_direction,
                               int y_direction)

key_move_pointer

public void key_move_pointer(int x_direction,
                             int y_direction)

key_process

public boolean key_process()

key_process_no_prefix

public boolean key_process_no_prefix()

key_process_prefix0

public boolean key_process_prefix0()

key_process_prefix1

public boolean key_process_prefix1()

key_click_button

public void key_click_button(int button)

key_search_client

public void key_search_client()

key_switch_focus

public void key_switch_focus()

key_warp_pointer

public void key_warp_pointer()

manage

public void manage(Client client)

maximize

public void maximize(Client client,
                     boolean full_screen)

minimize

public void minimize(Client client)

next_client

public Client next_client(Client from,
                          boolean reverse)

next_client_normal

public Client next_client_normal(Client from,
                                 boolean reverse)
See Also:
next_client(Client, boolean)

next_client_same_class

public Client next_client_same_class(Client from,
                                     boolean reverse)
See Also:
next_client(Client, boolean)

next_client_different_class

public Client next_client_different_class(Client from,
                                          boolean reverse)
See Also:
next_client(Client, boolean)

next_client_first_char

public Client next_client_first_char(Client from,
                                     boolean reverse,
                                     char c,
                                     boolean all)
See Also:
next_client(Client, boolean)

when

public void when(Event event)

read_and_dispatch_event

public void read_and_dispatch_event()

register_fall_back

public void register_fall_back(Client client)

relocate

public void relocate(Client client)

restore_size

public void restore_size(Client client)

save_size

public void save_size(Client client)

scale_size

public void scale_size(Client client,
                       double factor)

scan_children

public void scan_children()

set_focus

public void set_focus(Client client,
                      boolean warp_pointer)

when_button_press

public void when_button_press(ButtonPress event)

when_client_message

public void when_client_message(ClientMessage event)

when_configure_request

public void when_configure_request(ConfigureRequest event)

when_destroy_notify

public void when_destroy_notify(DestroyNotify event)

when_key_press

public void when_key_press(KeyPress event)

when_key_release

public void when_key_release(KeyRelease event)
Handle *-TAB key release.


when_property_notify

public void when_property_notify(PropertyNotify event)

when_map_request

public void when_map_request(MapRequest event)

when_map_notify

public void when_map_notify(MapNotify event)

when_quit

public void when_quit()

when_unmap_notify

public void when_unmap_notify(UnmapNotify event)

toggle_focus

public void toggle_focus(Client client)

unhide

public void unhide(Client client)

unhide_all

public void unhide_all()

unhide_same_class

public void unhide_same_class(Client client)

update_client_order

public void update_client_order(Client client)

main

public static void main(java.lang.String[] args)
                 throws NotFoundException
Throws:
NotFoundException