Window Manager Control Module




The window manager control module (xctrl) is a Lua module which allows you to query and manipulate various aspects of an X11 window manager and the windows it manages. It is based largely on Tomas Styblo's wmctrl command line tool, but has been transformed into a C library with a Lua binding. It is intended to work with any EWMH / NetWM compatible window manager. Because support for these standards varies with different window managers and clients, some features might not work in all situations.

The functions described below are intended to be used in object-oriented style, for example:

  require "xctrl"             -- load the module
  local xc=xctrl.new()        -- create a new xctrl object
  local win=xc:get_active_win()   -- find the currently active window
  xc:close_win(win)           -- close the window

Note that only one instance of the xctrl object at a time is allowed to be in use. If for some reason you need to re-initialize a new object, you should set the old one to nil and call collectgarbage() twice before trying to create another new object. This will help insure that the first instance is properly cleaned up.


xctrl functions


new (display [,as_utf8 [,charset]]) -- Create a new xctrl object.
get_win_list () -- Return a list of all top-level windows.
get_win_title (win) -- Get the title of a window.
set_win_title (win,title) -- Set the title of a window.
get_win_class () -- Get the class name of a window.
activate_win (win [,switch]) -- Raise and focus a window.
iconify_win(win) -- Change a window's state to iconic.
set_win_state (win,mode,p1 [,p2]) -- Change a window's state properties.
set_win_geom (win,[x,y,w,h]|[t][,g]) -- Move and/or resize a window
get_win_geom (win) -- Get a window's size and position
get_win_frame (win) -- Get the extents of a window's frame
get_win_type (win) -- Get the functional type of a window
set_win_decor (win, decor) -- Set the window manager decorations for a window
get_active_win () -- Get the id of the currently active window.
pick_win ( [button] ) -- Get the id of a window by clicking it with the mouse.
root_win () -- Get the id of the display's root window.
set_desk_of_win (win,desk) -- Move a window onto another desktop.
get_desk_of_win (win) -- Get the index of a window's desktop.
get_pid_of_win (win) -- Get the process id of a window.
close_win (win) -- Try to close a window gracefully.
get_win_client (win) -- Get a window's client machine name.
get_num_desks () -- Get the total number of desktops.
set_num_desks () -- Set the total number of desktops.
get_curr_desk () -- Get the index of the current active desktop.
set_curr_desk (desk) -- Switch to another desktop
get_display () -- Return the the X11 display name.
get_wm_win () -- Get the window manager's information window.
get_wm_name () -- Get the window manager's name.
get_wm_class () -- Get the window manager's class name.
get_wm_pid () -- Get the window manager's process id.
get_desk_name (desk) -- Get the name of a desktop.
get_workarea (desk) -- Get the effective working dimensions of a desktop.
get_desk_geom (desk) -- Get the overall dimensions of a desktop.
set_desk_vport (desk,x,y) -- Set a desktop's viewport x-y coordinates.
set_desk_geom (desk,w,h) -- Set a desktop's dimensions.
set_showing_desk (showing) -- Set window manager's "showing desktop" mode.
get_showing_desk () -- Get window manager's "showing desktop" mode.
set_selection(text[,mode[,utf8]]) -- Push text into X selection, clipboard, or cut buffer.
get_selection ( [mode [,utf8] ) -- Retreive text from X selection, clipboard, or cut buffer.
send_keys (win,keys) -- Send simulated keyboard actions to a window.
do_events( [count] ) -- Flush the X server's event queue.
listen (event_handler) -- Monitor the window manager for events.
convert_locale (str,from,to) -- Convert string between locales.


new ([display [,as_utf8 [,charset]]])

Returns a new xctrl object. The default display is used if none was specified. If the optional as_utf8 argument is true, xctrl will attempt to use UTF-8 encoding for all strings passed to and from X11. If the optional charset string argument is present, it will try to use that value for character set conversions, otherwise it will use the $CHARSET environment variable if present, or fall back to a default of ISO_8859-1 .


get_win_list ()

Returns an indexed list of all top-level window id numbers on the current display.


get_win_title (win)

Returns the title bar text of the specified window id.


set_win_title (win,title)

Sets the title bar text of the specified window id.


get_win_class ()

Returns the X11 class name (WM_CLASS property) of the specified window id.


activate_win (win [,switch])

Raises the specified window and gives it the focus. If the window is not on the current desktop, the desktop containing the window will also be activated, unless the optional switch argument is false.


iconify_win (win)

Changes the specified window's state to iconic or "minimized".


set_win_state (win,mode,p1 [,p2])

Modify up to two of the window's properties simultaneously. The property change is achived by using the _NET_WM_STATE request.

The mode string argument must be one of: "add", "remove" or "toggle"

The supported property names (for p1 and p2) are:
  "modal", "sticky", "maximized_vert", "maximized_horz", "shaded", "skip_taskbar", "skip_pager", "hidden", "fullscreen", "above" and "below" .




set_win_geom (win,[x,y,w,h]|[t][,g])

Adjust the location and/or size of the window.

The x, y, w, h arguments are usually integers, but any of them may be nil, in which case that value will be ignored (i.e. unchanged.)

For the alternate form, t is a table in the same format as returned by get_win_geom().

Thus the following two calls are equivalent:
  set_win_geom(win, 32, 64, 640, 480)
  set_win_geom(win, {x=32,y=64,w=640,h=480})

The final argument g is optional and specifies the "gravity" (direction) of a resize operation.
If present, it must be one of the following strings:
  "default", "northwest", "north", "northeast", "west", "center", "east", "southwest", "south", "southeast", "static"


get_win_geom (win)

If successful, returns a table containing the x, y, w and h values of the specified window.

On failure, returns nil plus an error message.


get_win_frame (win)

If successful, returns a table containing the keys l, r, t, b which represent (respectively) the left, right, top, and bottom extents of the frame for the specified window.

On failure, returns nil plus an error message.




get_win_type (win)

Returns a string representing the functional type of the specified window.

The returned string will be one of:
  "desktop" -- A sreen-sized window containing desktop icons, usually kept below other windows.
  "dock" -- A dock or panel, usually kept on top of all other windows.
  "toolbar" -- An undocked or "torn off" toolbar window.
  "menu" -- A "torn off" menu panel.
  "utility" -- A small persistent window, such as a palette or toolbox.
  "splash" -- A splash screen, temporarily displayed on application start-up.
  "dialog" -- A dialog box or "transient" window.
  "normal" -- A normal, top-level window.
  "unsupported" -- The window manager does not support this property.

Note: Not all windows set this property, even if the window manager supports it. If a window's _NET_WM_WINDOW_TYPE property is not set, the type is assumed to be "dialog" if it has a WM_TRANSIENT_FOR property, or "normal" otherwise.


set_win_decor (win, decor)

Attempts to set the window manager decorations for the specified window.

The decor argument is a table containing a list of strings, the following strings are valid elements for the table:
  "none" -- The window will have no decorations.
  "all" -- The window will have all decorations.
  "border" -- The window will have a border.
  "resize" -- The window will be resizable.
  "title" -- The window will have a title bar.
  "maximize" -- The title bar will have a maximize button.
  "close" -- The title bar will have a close button.

Note: When the "none" or "all" string is used, it must be the only item in the list.


get_active_win ()

Returns the window id number of the currently active window.


pick_win ( [button] )

Displays a "crosshair" mouse cursor allowing the user to select a window by mouse click.

By default any button click selects the window, but the optional button argument allows you to specify which mouse button (1,2,3) will trigger the selection event. For example, you might want to ignore a left-click to minimize some other windows, and instead use a right-click (the third button) to pick the window you want.

Caution: Don't specify button number three if you only have a two-button mouse!

Returns the window id number of the clicked window.


root_win ()

Returns the window id of the window manager's root window.


set_desk_of_win (win,desk)

Moves the window to the desktop at the specified desk index.

(Note that the desktop indexes in Lua begin at one, not zero.)


get_desk_of_win (win)

Returns the index of the desktop that contains the specified window.


get_pid_of_win (win)

Returns the process id (PID) of the specified window, provided the application exports the _NET_WM_PID property.


close_win (win)

Attempts to gracefully close the specified window.




get_win_client (win)

Returns the client machine's name, provided the application exports the WM_CLIENT_MACHINE property.


get_num_desks ()

Returns the configured number of desktops for the window manager.


set_num_desks ()

Changes the configured number of desktops for the window manager.

(Not all window managers allow this.)


get_curr_desk ()

Returns the index number of the active desktop.

(Note that the desktop indexes in Lua begin at one, not zero.)


set_curr_desk (desk)

Switch to the desktop at index desk.


get_display ()

Returns the name of the current display.


get_wm_win ()

Returns the window id of the window manager's SUPPORTING_WM_CHECK window.

This value is of little use, but unless it returns non-zero the get_wm_name, get_wm_class and get_wm_pid functions will also fail.


get_wm_name ()

Returns the window manager's name property (if supported).


get_wm_class ()

Returns the window manager's class property (if supported).


get_wm_pid ()

Returns the window manager's process id (if supported).


get_desk_name (desk)

Returns the name of the desktop at index desk.


get_workarea (desk)

Returns a table containing the x, y, w and h values of the effective working area for the desktop at index desk. This may be smaller than the actual desktop dimensions since it should exclude "reserved" areas like struts and taskbars.


get_desk_geom (desk)

Returns a table containing the x, y, w and h values of the overall dimensions for the desktop at index desk.


set_desk_vport (desk,x,y)

Sets the top left coordinates of the desktop (if supported).


set_desk_geom (desk,w,h)

Sets the width and height of the desktop (if supported).


set_showing_desk (showing)

Sets the window manager's _NET_SHOWING_DESKTOP property (if supported).


get_showing_desk ()

Returns the window manager's _NET_SHOWING_DESKTOP property (if supported).


set_selection (text [,mode [,utf8]] )

Pushes the text into the X selection, clipboard, or cut buffer.

The mode argument determines where the text is sent, and can be one of:
  "p" : The primary selection (default).
  "s" : The secondary selection.
  "c" : The clipboard.
  "b" : The cut buffer.

If the optional utf8 argument is true, the text is considered to be in UTF-8 format.

Note: For all modes except "b" this function is blocking, and will not return until another application requests the text or steals the selection.


get_selection ( [mode [,utf8]] )

Retreives text from X selection, clipboard, or cut buffer.

The mode argument determines which item is requested, as described in the set_selection() function.

If the optional utf8 argument is true, the text is requested to be in UTF-8 format.


send_keys (win,keys)

Sends a series of keystrokes to the specified window, as if they were typed on the keyboard.

Most printable characters are passed verbatim, but the following sequences are special:

\nThe  Enter  key.
\tThe  Tab  key.
\27The  Esc  key.
\bThe  Backspace  key.
^The next key is passed with the  Ctrl  key pressed.
~The next key is passed with the  Alt  key pressed.
+The next key is passed with the  Shift  key pressed.
%^A literal  ^
%~A literal  ~
%+A literal  +
%%A literal  %
%FxxA function key, where xx is  01  thru  12
%.The  Delete  key.
%0The  Insert  key.
%1The  End  key.
%2The  Down  arrow key.
%3The  PageDown  key.
%4The  Left  arrow key.
%6The  Right  arrow key.
%7The  Home  key.
%8The  Up  arrow key.
%9The  PageUp  key.

Hint: Key sequences for the delete, insert and navigation keys correspond to the alternate functions of the numeric keypad on a standard U.S. keyboard.

Since this function only sends keystrokes to the application's top-level window, complex applications with nested widgets and cascading menus might not exhibit consistent results.


do_events ( [count] )

Causes the library to sleep for approximately one-tenth of a second, and then sends an XSync() message to the display, which flushes the event queue and waits until all requests have been received and processed by the X server. This process is performed count number of times (default: once).


listen ( handler )

Continuously "listens" for window manager events, and runs the function handler each time an event occurs.

The event handler function should be in the form of:

  function event_handler(ev,id)
    -- handle the event here
    return true
  end

Note that the handler must return true to continue listening, or false to stop listening.

The value of the string ev will be one of:
  "w" -- A new window was created.
  "x" -- The window was closed (its id is no longer valid!).
  "a" -- The window was activated (gained focus).
  "i" -- The window became inactive (lost focus).
  "g" -- The window's exterior geometry changed (size, position, or decoration).
  "t" -- The window's title text changed.
  "s" -- The window's state changed (iconified, maximized, sticky, layer, etc.)
  "d" -- Switched desktops: in this case id is the index of the activated desktop.

Unless noted above, the value of the integer id is the ID of the window that triggered the event.

Note: Rather than using expensive string comparisons on the value of ev, it may be more efficient to set up a table of functions as illustrated below:

  local xc=xctrl.new()

  local event_callbacks = {
    w = function(id) 
          io.write("A new window ",id, " was created.\n")
          return true 
        end,
    x = function(id)
          io.write("The window ", id, " was closed.\n")
          return true
        end,
    a = function(id)
          io.write("The window ", id, " was activated.\n")
          return true
        end,
    i = function(id)
          io.write("The window ", id, " became inactive.\n")
          return true
        end,
    g = function(id) 
          io.write("The window ", id, " geometry changed.\n") 
          return true
        end,
    t = function(id) 
        io.write("The window ", id, " title changed.\n") 
        return true
      end,
    s = function(id) 
        io.write("The window ", id, " state changed.\n") 
        return true
      end,
    d = function(id) 
          io.write("Switched to desktop number ", id, ".\n")
          return true
        end
  }

  function my_event_handler(ev,id)
    local callback=event_callbacks[ev]
    if callback ~= nil then
      return callback(id)
    else
      return true
    end
  end

  xc:listen(my_event_handler)



convert_locale (str,from,to)

Converts the string str from its original encoding from into the new encoding to and returns the new string.