Class: XDo::XWindow

Inherits:
Object
  • Object
show all
Defined in:
lib/xdo/xwindow.rb

Overview

This class represents a window on the screen. Each window is uniquely identified by an internal ID; before you can create a reference to a window (a XWindow object) you have to obtain the internal ID of that window and pass it into XWindow.new. Or you use the class methods of this class, notably XWindow.active_window.

Via the XWindow object you get you can manipulate a window in serveral ways, e.g. you can move or resize it. Some methods are not available on every window manager: XWindow.active_window, XWindow.desktop_num, XWindow.desktop_num=, XWindow.desktop, XWindow.desktop=, XWindow.from_active, #raise, #activate, #desktop, #desktop=. Some of them may be available, some not. On my machine (an Ubuntu Lucid) for example I can use active_window, desktop_num and #activate, but not #raise or #desktop=. Those methods are tagged with the sentence “Part of the EWMH standard XY”. Not all parts of the EWMH standard are provided by every window manager.

As of version 0.0.4 the way to search for window is about to change. The old version where you passed a hash with symbols has been deprecated (and you get warnings about this if you use it) in favor of passing those symbols as a rest argument. See XWindow.search for more details.

You should also be aware of the fact that XDo is about to support Regexp objects in XWindow.search. In future versions (i.e. after the next minor release) strings always mean an exact title/class/whatever match. For parts, you have to use Regular Expressions. There is a culprit, though. xdotool doesn’t use Ruby’s Regular Expressions engine Oniguruma and expects C-style regexps. I don’t know about the differences - but if you’re absolutely sure your window title matches that wonderful three-line extended regexp and xdotool doesn’t find it, you may email me at sutniuq@@gmx@net explaining which construct defeats xdotool. I will then setup a list over time which states which constructs don’t work.

Be very careful with the methods that are part of the two desktop EWMH standards. After I set the number of desktops and changed the current desktop, I had to reboot my system to get the original configuration back. I don’t know if I’m not using xdotool correct, but neither my library nor xdotool itself could rescue my desktop settings. Btw, that’s the reason why it’s not in XDo’s unit tests (but it should work; at least in one way…).

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id) ⇒ XWindow

Creates a new XWindow object from an internal ID.

Parameters

id

The internal ID to create the window from.

Return value

The newly created XWindow object.

Example

id = XWindow.search(/edit/)[1]
xwin = XWindow.new(id)

Remarks

See also many class methods of the XWindow class which allow you to forget about the internal ID of a window.



561
562
563
# File 'lib/xdo/xwindow.rb', line 561

def initialize(id)
  @id = id.to_i
end

Instance Attribute Details

#idObject (readonly)

The internal ID of the window.



45
46
47
# File 'lib/xdo/xwindow.rb', line 45

def id
  @id
end

Class Method Details

.active_windowObject

Returns the internal ID of the currently focused window.

Return value

The ID of the found window.

Raises

XError

Error invoking xdotool.

Example

p XDo::XWindow.active_window #=> 41943073

Remarks

This method is more reliable than #focused_window, but never finds an invisible window.

Part of the EWMH standard ACTIVE_WINDOW.

Raises:



212
213
214
215
216
217
218
# File 'lib/xdo/xwindow.rb', line 212

def active_window
  err = ""
  out = ""
  Open3.popen3("#{XDo::XDOTOOL} getactivewindow"){|stdin, stdout, stderr| out = stdout.read; err = stderr.read}
  raise(XDo::XError, err) unless err.empty?
  return Integer(out)
end

.desktopObject

Returns the number of the active desktop.

Return value

The number of the currently shown desktop.

Raises

XError

Error invoking xdotool.

Example

p XDo::XWindow.desktop #=> 0

Remarks

Although Ubuntu systems seem to have several desktops, that isn’t completely true. An usual Ubuntu system only has a single working desktop, on which Ubuntu sets up an arbitrary number of other “desktop views” (usually 4). That’s kind of cheating, but I have not yet find out why it is like that. Maybe it’s due to the nice cube rotating effect? That’s the reason, why the desktop-related methods don’t work with Ubuntu.

Part of the EWMH standard CURRENT_DESKTOP.

Raises:



302
303
304
305
306
307
308
# File 'lib/xdo/xwindow.rb', line 302

def desktop
  err = ""
  out = ""
  Open3.popen3("#{XDo::XDOTOOL} get_desktop"){|stdin, stdout, stderr| out = stdout.read; err = stderr.read}
  raise(XDo::XError, err) unless err.empty?
  Integer(out)
end

.desktop=(num) ⇒ Object

Change the view to desktop num.

Parameters

num

The 0-based index of the desktop you want to switch to.

Return value

num.

Raises

XError

Error invoking xdotool.

Example

XDo::XWindow.desktop = 1

Remarks

Although Ubuntu systems seem to have several desktops, that isn’t completely true. An usual Ubuntu system only has a single working desktop, on which Ubuntu sets up an arbitrary number of other “desktop views” (usually 4). That’s kind of cheating, but I have not yet find out why it is like that. Maybe it’s due to the nice cube rotating effect? That’s the reason, why the desktop-related methods don’t work with Ubuntu.

Part of the EWMH standard CURRENT_DESKTOP.

Raises:



281
282
283
284
285
286
# File 'lib/xdo/xwindow.rb', line 281

def desktop=(num)
  err = ""
  Open3.popen3("#{XDo::XDOTOOL} set_desktop #{num}"){|stdin, stdout, stderr| err << stderr.read}
  raise(XDo::XError, err) unless err.empty?
  num
end

.desktop_nameObject

Deprecated.



445
446
447
448
# File 'lib/xdo/xwindow.rb', line 445

def desktop_name
  warn("#{caller.first}: Deprecation warning: XWindow.desktop_name doesn't do anything anymore.")
  "x-nautilus-desktop"
end

.desktop_name=(name) ⇒ Object

Deprecated.



440
441
442
# File 'lib/xdo/xwindow.rb', line 440

def desktop_name=(name)
  warn("#{caller.first}: Deprecation warning: XWindow.desktop_name= doesn't do anything anymore.")
end

.desktop_numObject

Get the number of working desktops.

Return value

The number of desktops.

Raises

XError

Error invoking xdotool.

Example

p XDo::XWindow.desktop_num = 1

Remarks

Although Ubuntu systems seem to have several desktops, that isn’t completely true. An usual Ubuntu system only has a single working desktop, on which Ubuntu sets up an arbitrary number of other “desktop views” (usually 4). That’s kind of cheating, but I have not yet find out why it is like that. Maybe it’s due to the nice cube rotating effect? That’s the reason, why the desktop-related methods don’t work with Ubuntu.

Part of the EWMH standard WM_DESKTOP.

Raises:



257
258
259
260
261
262
263
# File 'lib/xdo/xwindow.rb', line 257

def desktop_num
  err = ""
  out = ""
  Open3.popen3("#{XDo::XDOTOOL} get_num_desktops"){|stdin, stdout, stderr| out << stdout.read; err << stderr.read}
  raise(XDo::XError, err) unless err.empty?
  Integer(out)
end

.desktop_num=(num) ⇒ Object

Set the number of working desktops.

Parameters

num

The number of desktops you want to exist.

Return value

num.

Raises

XError

Error invoking xdotool.

Example

XDo::XWindow.desktop_num = 2

Remarks

Although Ubuntu systems seem to have several desktops, that isn’t completely true. An usual Ubuntu system only has a single working desktop, on which Ubuntu sets up an arbitrary number of other “desktop views” (usually 4). That’s kind of cheating, but I have not yet find out why it is like that. Maybe it’s due to the nice cube rotating effect? That’s the reason, why the desktop-related methods don’t work with Ubuntu.

Part of the EWMH standard WM_DESKTOP.

Raises:

  • (XDo::Error)


236
237
238
239
240
241
# File 'lib/xdo/xwindow.rb', line 236

def desktop_num=(num)
  err = ""
  Open3.popen3("#{XDo::XDOTOOL} set_num_desktops #{num}"){|stdin, stdout, stderr| err << stderr.read}
  raise(XDo::Error, err) unless err.empty?
  num
end

.exists?(name, *opts) ⇒ Boolean

Checks if a window exists.

Parameters

name

The name of the window to look for. Either a string or a Regular Expression; however, there’s no guaranty that xdotool gets the regexp right. Simple ones should work, though.

[*opts ([:name, :class, :classname]) Search parameters. See XWindow.search.

Return value

true or false.

Example

p XWindow.exists?("gedit") #=> true
p XWindow.exists?(/^gedit/) #=> false

Remarks

It may be a good idea to pass :onlyvisible as a search parameter.

Returns:

  • (Boolean)


60
61
62
63
64
65
66
67
# File 'lib/xdo/xwindow.rb', line 60

def exists?(name, *opts)
  if opts.first.kind_of?(Hash)
    warn("#{caller.first}: Deprecation Warning: Using a hash as further arguments is deprecated. Pass the symbols directly.")
    opts = opts.first.keys
  end
  
  !search(name, *opts).empty?
end

.focus_desktopObject Also known as: activate_desktop

Deprecated. Just calls XWindow.unfocus internally.



451
452
453
454
# File 'lib/xdo/xwindow.rb', line 451

def focus_desktop
  warn("#{caller.first}: Deprecation warning: XWindow.focus_desktop is deprecated. Use XWindow.unfocus instead.")
  unfocus
end

.focused_window(notice_children = false) ⇒ Object

Returns the internal ID of the currently focused window.

Parameters

notice_children

(false) If true, childwindows are noticed and you may get a child window instead of a toplevel window.

Return value

The internal ID of the found window.

Raises

XError

Error invoking xdotool.

Example

p XDo::XWindow.focused_window #=> 41943073
p XDo::XWindow.focused_window(true) #=> 41943074

Remarks

This method may find an invisible window, see active_window for a more reliable method.

Raises:



193
194
195
196
197
198
199
# File 'lib/xdo/xwindow.rb', line 193

def focused_window(notice_children = false)
  err = ""
  out = ""
  Open3.popen3("#{XDo::XDOTOOL} getwindowfocus #{notice_children ? "-f" : ""}"){|stdin, stdout, stderr| out << stdout.read; err << stderr.read}
  raise(XDo::XError, err) unless err.empty?
  return out.to_i
end

.from_activeObject

Creates a XWindow by calling active_window.

Return value

The newly created XWindow object.

Example

xwin = XDo::XWindow.from_active

Remarks

This method does not find invisible nor child windows; if you want that, you should take a look at XWindow.from_focused.



385
386
387
# File 'lib/xdo/xwindow.rb', line 385

def from_active
  new(active_window)
end

.from_focused(notice_childs = false) ⇒ Object

Creates a XWindow by calling XWindow.focused_window with the given parameter.

Parameters

notice_children

(false) If true, you may get a child window as the active window.

Return value

The newly created XWindow objects.

Example

xwin = XDo::XWindow.from_focused

Remarks

The XWindow.focused_window method is a bit dangerous, since it may find an invisible window. Use XWindow.from_active if you don’t want that.



373
374
375
# File 'lib/xdo/xwindow.rb', line 373

def from_focused(notice_childs = false)
  new(focused_window(notice_childs))
end

.from_name(name, *opts) ⇒ Object

Deprecated. Use XWindow.from_search or XWindow.from_title instead.



340
341
342
343
# File 'lib/xdo/xwindow.rb', line 340

def from_name(name, *opts)
  warn("#{caller.first}: Deprecation Warning: ::from_name is deprecated. Use ::from_search if you want the old behaviour with the ability to specify all search parameters, or ::from_title if you just want to look through the window titles.")
  from_search(name, *opts)
end

.from_nullObject

Creates a invalid XWindow.

Return value

The newly created XWindow object.

Example

nwin = XDo::XWindow.from_null

Remarks

The handle the returned XWindow object uses is zero and therefore invalid. You can’t call #move, #resize or other methods on it, but it may be useful for unsetting focus. See also the XWindow.unfocus method.



421
422
423
# File 'lib/xdo/xwindow.rb', line 421

def from_null
  new(0) #Zero never is a valid window ID. Even the root window has another ID.
end

.from_rootObject

Creates a XWindow refering to the root window.

Return value

The newly created XWindow object.

Example

rwin = XDo::XWindow.from_root


407
408
409
# File 'lib/xdo/xwindow.rb', line 407

def from_root
  new(root_id)
end

.from_search(name, *opts) ⇒ Object

Creates a XWindow by calling search with the given parameters. The window is created from the first ID found.

Parameters

name

The name of the window to look for. Either a string or a Regular Expression; however, there’s no guaranty that xdotool gets the regexp right. Simple ones should work, though.

[*opts ([:name, :class, :classname]) Search parameters. See XWindow.search.

Return value

The created XWindow object.

Raises

XError

Error invoking xdotool.

Example

#Exact title/class/classname match
xwin = XDo::XWindow.from_search("xwindow.rb - SciTE")
#Part match via regexp
xwin = XDo::XWindow.from_search(/SciTE/)
#Part match via string - DEPRECATED.
xwin = XDo::XWindow.from_search("SciTE")
#Only search the window classes
xwin = XDo::XWindow.from_search(/SciTE/, :class)

Raises:



328
329
330
331
332
333
334
335
336
337
# File 'lib/xdo/xwindow.rb', line 328

def from_search(name, *opts)
  if opts.first.kind_of?(Hash)
    warn("#{caller.first}: Deprecation Warning: Using a hash as further arguments is deprecated. Pass the symbols directly.")
    opts = opts.first.keys
  end
  
  ids = search(name, *opts)
  raise(XDo::XError, "The window '#{name}' wasn't found!") if ids.empty?
  new(ids.first)
end

.from_title(title) ⇒ Object

Same as XWindow.from_search, but only looks for the window’s titles to match.

Parameters

title

The title of the window to look for. Either a string or a Regular Expression; however, there’s no guaranty that xdotool gets the regexp right. Simple ones should work, though.

Return value

A XWindow object made up from the first window ID found.

Raises

XError

Error invoking xdotool.

Example

#Exact string match
xwin = XDo::XWindow.from_title("xwindow.rb - SciTE")
#Part match via regexp
xwin = XDo::XWindow.from_title(/SciTE/)
#Part match via string - DEPRECATED.
xwin = XDo::XWindow.from_title("SciTE")


359
360
361
# File 'lib/xdo/xwindow.rb', line 359

def from_title(title)
  from_search(title, :name)
end

.id_exists?(id) ⇒ Boolean

Checks wheather the given ID exists or not.

Parameters

id

The ID to check for.

Return value

true or false.

Example

p XWindow.id_exits?(29360674) #=> true
p XWindow.id_exists?(123456) #=> false

Returns:

  • (Boolean)


77
78
79
80
81
82
# File 'lib/xdo/xwindow.rb', line 77

def id_exists?(id)
  err = ""
  Open3.popen3("#{XDo::XWININFO} -id #{id}"){|stdin, stdout, stderr| err << stderr.read}
  return false unless err.empty?
  return true
end

.minimizeObject

Minimizes the active window. There’s no way to restore a specific minimized window. Available after requireing “xdo/keyboard”.

Return value

Undefined.

Raises

NotImplementedError

You didn’t require ‘xdo/keyboard’.

Example

XDo::XWindow.minimize

Raises:

  • (NotImplementedError)


481
482
483
484
# File 'lib/xdo/xwindow.rb', line 481

def minimize
  raise(NotImplementedError, "You have to require 'xdo/keyboard' before you can use #{__method__}!") unless defined? XDo::Keyboard
  XDo::Keyboard.key("Alt+F9")
end

.root_idObject

Returns the ID of the root window.

Return value

The ID of the root window.

Example

p XDo::XWindow.root_id #=> 346


394
395
396
397
398
399
400
# File 'lib/xdo/xwindow.rb', line 394

def root_id
  out = ""
  err = ""
  Open3.popen3("#{XDo::XWININFO} -root"){|stdin, stdout, stderr| out << stdout.read.strip; err << stderr.read.strip}
  Kernel.raise(XDo::XError, err) unless err.empty?
  Integer(out.lines.to_a[0].match(/Window id:(.*?)\(/)[1].strip)
end

.search(str, *opts) ⇒ Object

Search for a window name to get the internal ID of a window.

Parameters

str

The name of the window to look for. Either a string or a Regular Expression; however, there’s no guaranty that xdotool gets the regexp right. Simple ones should work, though.

[*opts ([:name, :class, :classname]) Search parameters.

Possible search parameters

Copied from the xdotool manpage:

class

Match against the window class.

classname

Match against the window classname.

name

Match against the window name. This is the same string that is displayed in the window titlebar.

onlyvisible

Show only visible windows in the results. This means ones with map state IsViewable.

Return value

An array containing the IDs of all found windows or an empty array if none was found.

Example

#Look for every window with "gedit" in it's title, class or classname
XDo::XWindow.search("gedit")
#Look for every window whose title, class or classname ends with "SciTE"
XDo::XWindow.search(/SciTE$/)
#Explicitly only search the titles of visible windows
XDo::XWindow.search("gedit", :name, :onlyvisible)


154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/xdo/xwindow.rb', line 154

def search(str, *opts)
  if opts.first.kind_of?(Hash)
    warn("#{caller.first}: Deprecation Warning: Using a hash as further arguments is deprecated. Pass the symbols directly.")
    opts = opts.first.keys
  end
  opts = [:name, :class, :classname] if opts.empty?
  
  #Allow Regular Expressions. Since I can't pass them directly to the command line,
  #I need to get their source. Otherwise we want an exact match, therefore the line
  #begin and line end anchors need to be set around the given string.
  str = str.source if str.kind_of?(Regexp)
  #TODO
  #The following is the new behaviour that will be activated with the next minor version.
  #See DEPRECATE.rdoc.
  #str = if str.kind_of?(Regexp)
    #str.source
  #else
    #"^#{str.to_str}$"
  #end
  
  cmd = "#{XDo::XDOTOOL} search "
  opts.each{|sym| cmd << "--#{sym} "}
  cmd << "'" << str << "'"
  #Don't handle errors since we want an empty array in case of an error
  Open3.popen3(cmd){|stdin, stdout, stderr| stdin.close_write; stdout.read}.lines.to_a.collect{|l| l.strip.to_i}
end

.toggle_maximizeObject

Maximize or normalize the active window if already maximized. Available after requireing “xdo/keyboard”.

Return value

Undefined.

Raises

NotImplementedError

You didn’t require ‘xdo/keyboard’.

Example

XDo::XWindow.minimize
XDo::XWindow.toggle_maximize

Raises:

  • (NotImplementedError)


495
496
497
498
# File 'lib/xdo/xwindow.rb', line 495

def toggle_maximize
  raise(NotImplementedError, "You have to require 'xdo/keyboard' before you can use #{__method__}!") unless defined? XDo::Keyboard
  XDo::Keyboard.key("Alt+F10")
end

.toggle_minimize_allObject

Minimize all windows (or restore, if already) by sending [CTRL][ALT][D]. Available after requireing “xdo/keyboard”.

Return value

Undefined.

Raises

NotImplementedError

You didn’t require ‘xdo/keyboard’.

Example

#Everything will be minimized:
XDo::XWindow.toggle_minimize_all
#And now we'll restore everything.
XDo::XWindow.toggle_minimize_all

Raises:

  • (NotImplementedError)


468
469
470
471
# File 'lib/xdo/xwindow.rb', line 468

def toggle_minimize_all
  raise(NotImplementedError, "You have to require 'xdo/keyboard' before you can use #{__method__}!") unless defined? XDo::Keyboard
  XDo::Keyboard.ctrl_alt_d
end

.unfocus(sync = true) ⇒ Object

Unsets the input focus by setting it to the invalid NULL window.

Parameters

sync

(true) If true, this method blocks until the input focus has been unset.

Return value

nil.

Example

win = XDo::XWindow.from_active
win.focus
XDo::XWindow.unfocus


435
436
437
# File 'lib/xdo/xwindow.rb', line 435

def unfocus(sync = true)
  from_null.focus(sync)
end

.wait_for_close(name, *opts) ⇒ Object

Waits for a window to close.

Parameters

name

The name of the window to look for. Either a string or a Regular Expression; however, there’s no guaranty that xdotool gets the regexp right. Simple ones should work, though.

[*opts ([:name, :class, :classname]) Search parameters. See XWindow.search.

Return value

nil.

Example

#Wait for a window with "gedit" somewhere in it's title
XDo::XWindow.wait_for_close("gedit")
#Waits for a window whose title ends with "ends_with_this":
XDo::XWindow.wait_for_close(/ends_with_this$/)
#It's quite useful to combine this method with the Timeout module:
require "timeout"
Timeout.timeout(3){XDo::XWindow.wait_for_close("gedit")}


124
125
126
127
128
129
130
131
132
# File 'lib/xdo/xwindow.rb', line 124

def wait_for_close(name, *opts)
  if opts.first.kind_of?(Hash)
    warn("#{caller.first}: Deprecation Warning: Using a hash as further arguments is deprecated. Pass the symbols directly.")
    opts = opts.first.keys
  end
  
  loop{break if !exists?(name, *opts);sleep(0.5)}
  nil
end

.wait_for_window(name, *opts) ⇒ Object

Waits for a window name to exist.

Parameters

name

The name of the window to look for. Either a string or a Regular Expression; however, there’s no guaranty that xdotool gets the regexp right. Simple ones should work, though.

[*opts ([:name, :class, :classname]) Search parameters. See XWindow.search.

Return value

The ID of the newly appeared window.

Example

#Wait for a window with "gedit" somewhere in it's title:
XDo::XWindow.wait_for_window("gedit")
#Wait for a window that ends with "ends_with_this":
XDo::XWindow.wait_for_window(/ends_with_this$/)
#It's useful to combine this method with the Timeout module:
require "timeout"
Timeout.timeout(3){XDo::XWindow.wait_for_window("gedit")}

Remarks

Returns immediately if the window does already exist.



100
101
102
103
104
105
106
107
108
# File 'lib/xdo/xwindow.rb', line 100

def wait_for_window(name, *opts)
  if opts.first.kind_of?(Hash)
    warn("#{caller.first}: Deprecation Warning: Using a hash as further arguments is deprecated. Pass the symbols directly.")
    opts = opts.first.keys
  end
  
  loop{break if exists?(name, *opts);sleep(0.5)}
  search(name, *opts).first
end

Instance Method Details

#abs_positionObject Also known as: position

The absolute position of the window on the screen.

Return value

A two-element array of form [x, y].

Raises

XError

Error executing xwininfo.

Example

p xwin.abs_position #=> [0, 51]


808
809
810
811
812
813
814
815
816
817
# File 'lib/xdo/xwindow.rb', line 808

def abs_position
  out = ""
  err = ""
  Open3.popen3("#{XDo::XWININFO} -id #{@id}"){|stdin, stdout, stderr| out << stdout.read; err << stderr.read}
  Kernel.raise(XDo::XError, err) unless err.empty?
  out = out.strip.lines.to_a
  x = out[2].match(/:\s+(\d+)/)[1]
  y = out[3].match(/:\s+(\d+)/)[1]
  [x.to_i, y.to_i]
end

#activate(sync = true) ⇒ Object

Activate a window. That is, bring it to top and give it the input focus.

Parameters

sync

(true) If true, this method blocks until the window has been activated.

Return value

Undefined.

Raises

XError

Error executing xdotool.

Example

xwin.activate

Remarks

This is the recommanded method to give a window the input focus, since it works on more window managers than #focus and also works across desktops.

Part of the EWMH standard ACTIVE_WINDOW.



714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
# File 'lib/xdo/xwindow.rb', line 714

def activate(sync = true)
  tried_focus = false
  begin
    err = ""
    opts = []
    opts << "--sync" if sync
    Open3.popen3("#{XDo::XDOTOOL} windowactivate #{opts.join(" ")} #{@id}"){|stdin, stdout, stderr| err << stderr.read}
    Kernel.raise(XDo::XError, err) unless err.empty?
  rescue XDo::XError
    #If no window is active, xdotool's windowactivate fails, 
    #because it tries to determine which is the currently active window. 
    unless tried_focus
      tried_focus = true
      focus
      retry
    else
      raise
    end
  end
end

#closeObject

Closes a window by activating it and then sending [ALT] + [F4].

Return value

nil.

Raises

NotImplementedError

You didn’t require “xdo/keyboard”.

Example

xwin.close

Remarks

A program could ask to save data.

Use #kill! to kill the process running the window.

Available after requireing “xdo/keyboard”.



896
897
898
899
900
901
902
# File 'lib/xdo/xwindow.rb', line 896

def close
  Kernel.raise(NotImplementedError, "You have to require 'xdo/keyboard' before you can use #{__method__}!") unless defined? XDo::Keyboard
  activate
  XDo::Keyboard.char("Alt+F4")
  sleep 0.5
  nil
end

#close!(timeout = 2) ⇒ Object

More aggressive variant of #close. Think of close! as the middle between #close and #kill!. It first tries to close the window by calling #close and if that does not succeed (within timeout seconds), it will call #kill!.

Paramters

timeout

(2) The time to wait before using #kill!, in seconds.

Return value

Undefined.

Raises

XError

Error executing xkill.

Example

xwin.close!

Remarks

Available after requireing “xdo/keyboard”.



918
919
920
921
922
923
924
925
926
927
928
929
930
931
# File 'lib/xdo/xwindow.rb', line 918

def close!(timeout = 2)
  Kernel.raise(NotImplementedError, "You have to require 'xdo/keyboard' before you can use #{__method__}!") unless defined? XDo::Keyboard
  #Try to close normally
  close
  #Check if it's deleted
  if exists?
    #If not, wait some seconds and then check again
    sleep timeout
    if exists?
      #If it's not deleted after some time, force it to close.
      kill!
    end
  end
end

#desktopObject

Get the desktop the window is on.

Return value

The 0-based index of the desktop this window resides on.

Raises

XError

Error executing xdotool.

Example

p xwin.desktop #=> 0

Remarks

Although Ubuntu systems seem to have several desktops, that isn’t completely true. An usual Ubuntu system only has a single working desktop, on which Ubuntu sets up an arbitrary number of other “desktop views” (usually 4). That’s kind of cheating, but I have not yet find out why it is like that. Maybe it’s due to the nice cube rotating effect? That’s the reason, why the desktop-related methods don’t work with Ubuntu.

Part of the EWMH standard CURRENT_DESKTOP.



771
772
773
774
775
776
777
# File 'lib/xdo/xwindow.rb', line 771

def desktop
  err = ""
  out = ""
  Open3.popen3("#{XDo::XDOTOOL} get_desktop_for_window #{@id}"){|stdin, stdout, stderr| out = stdout.read; err << stderr.read}
  Kernel.raise(XDo::XError, err) unless err.empty?
  Integer(out)
end

#desktop=(num) ⇒ Object

Move a window to a desktop.

Parameters

num

The 0-based index of the desktop you want the window to move to.

Return value

Undefined.

Raises

XError

Error executing xdotool.

Example

xwin.desktop = 3

Remarks

Although Ubuntu systems seem to have several desktops, that isn’t completely true. An usual Ubuntu system only has a single working desktop, on which Ubuntu sets up an arbitrary number of other “desktop views” (usually 4). That’s kind of cheating, but I have not yet find out why it is like that. Maybe it’s due to the nice cube rotating effect? That’s the reason, why the desktop-related methods don’t work with Ubuntu.

Part of the EWMH standard CURRENT_DESKTOP.



751
752
753
754
755
# File 'lib/xdo/xwindow.rb', line 751

def desktop=(num)
  err = ""
  Open3.popen3("#{XDo::XDOTOOL} set_desktop_for_window #{@id} #{num}"){|stdin, stdout, stderr| err << stderr.read}
  Kernel.raise(XDo::XError, err) unless err.empty?
end

#exists?Boolean

Returns true if the window exists.

Return value

true or false.

Example

p xwin.exists? #=> true

Returns:

  • (Boolean)


879
880
881
# File 'lib/xdo/xwindow.rb', line 879

def exists?
  XDo::XWindow.id_exists?(@id)
end

#focus(sync = true) ⇒ Object

Set the input focus to the window (but don’t bring it to the front).

Parameters

sync

(true) If true, this method blocks until the window got the input focus.

Return value

Undefined.

Raises

XError

Error invoking xdotool.

Example

xwin.focus

Remarks

This method may not work on every window manager. You should use activate, which is supported by more window managers.



630
631
632
633
634
635
636
# File 'lib/xdo/xwindow.rb', line 630

def focus(sync = true)
  err = ""
  opts = []
  opts << "--sync" if sync
  Open3.popen3("#{XDo::XDOTOOL} windowfocus #{opts.join(" ")} #{@id}"){|stdin, stdout, stderr| err << stderr.read}
  Kernel.raise(XDo::XError, err) unless err.empty?
end

#inspectObject

Human-readable output of form

<XDo::XWindow: "title" (window_id)>


567
568
569
# File 'lib/xdo/xwindow.rb', line 567

def inspect
  %Q|<#{self.class}: "#{title}" (#{id})>|
end

#kill!Object

Kills the process that runs a window. The window will be terminated immediatly, if that isn’t what you want, have a look at #close.

Return value

nil.

Raises

XError

Error executing xkill.

Example

xwin.kill!


942
943
944
945
946
947
948
# File 'lib/xdo/xwindow.rb', line 942

def kill!
  out = ""
  err = ""
  Open3.popen3("#{XDo::XKILL} -id #{@id}"){|stdin, stdout, stderr| out << stdout.read; err << stderr.read}
  Kernel.raise(XDo::XError, err) unless err.empty?
  nil
end

#map(sync = true) ⇒ Object

Maps a window to the screen (makes it visible).

Parameters

sync

(true) If true, this method blocks until the window has been mapped.

Return value

Undefined.

Raises

XError

Error invoking xdotool.

Example

xwin.unmap #Windows are usually mapped
xwin.map


660
661
662
663
664
665
666
# File 'lib/xdo/xwindow.rb', line 660

def map(sync = true)
  err = ""
  opts = []
  opts << "--sync" if sync
  Open3.popen3("#{XDo::XDOTOOL} windowmap #{opts.join(" ")} #{@id}"){|stdin, stdout, stderr| err << stderr.read}
  Kernel.raise(XDo::XError, err) unless err.empty?
end

#move(x, y, sync = true) ⇒ Object

Moves a window. xdotool is not really exact with the coordinates, special windows like Ubuntu’s panels make it placing wrong.

Parameters

x

The goal X coordinate.

y

The goal Y coordinate.

sync

(true) If true, this method blocks until the window has finished moving.

Return value

Undefined.

Raises

XError

Error executing xdotool.

Example

xwin.move(100, 100)
p xwin.abs_position #=> [101, 101]


610
611
612
613
614
615
616
# File 'lib/xdo/xwindow.rb', line 610

def move(x, y, sync = true)
  err = ""
  opts = []
  opts << "--sync" if sync
  Open3.popen3("#{XDo::XDOTOOL} windowmove #{opts.join(" ")} #{@id} #{x} #{y}"){|stdin, stdout, stderr| err << stderr.read}
  Kernel.raise(XDo::XError, err) unless err.empty?
end

#nonzero?Boolean

true if the internal ID is not zero.

Return value

nil or the internal ID.

Example

p xwin.nonzero? #=> 29361095

Returns:

  • (Boolean)


982
983
984
# File 'lib/xdo/xwindow.rb', line 982

def nonzero?
  @id.nonzero?
end

#raiseObject

Bring a window to the front (but don’t give it the input focus). Not implemented in all window managers.

Return value

Undefined.

Raises

XError

Error executing xdotool.

Example

xwin.raise


693
694
695
696
697
# File 'lib/xdo/xwindow.rb', line 693

def raise
  err = ""
  Open3.popen3("#{XDo::XDOTOOL} windowraise #{@id}"){|stdin, stdout, stderr| err << stderr.read}
  Kernel.raise(XDo::XError, err) unless err.empty?
end

#rel_positionObject

The position of the window relative to it’s parent window.

Return value

A two-element array of form [x, y].

Raises

XError

Error executing xdotool.

Example

p xwin.rel_position => [0, 51]


827
828
829
830
831
832
833
834
835
836
# File 'lib/xdo/xwindow.rb', line 827

def rel_position
  out = ""
  err = ""
  Open3.popen3("#{XDo::XWININFO} -id #{@id}"){|stdin, stdout, stderr| out << stdout.read; err << stderr.read}
  Kernel.raise(XDo::XError, err) unless err.empty?
  out = out.strip.lines.to_a
  x = out[4].match(/:\s+(\d+)/)[1]
  y = out[5].match(/:\s+(\d+)/)[1]
  [x.to_i, y.to_i]
end

#resize(width, height, use_hints = false, sync = true) ⇒ Object

Set the size of a window.

Parameters

width

The new width, usually in pixels.

height

The new height, usually in pixels.

use_hints

(false) If true, window sizing hints are used if they’re available. This is usually done when resizing terminal windows to a specific number of rows and columns.

sync

(true) If true, this method blocks until the window has finished resizing.

Return value

Undefined.

Raises

XError

Error executing xdotool.

Example

#Resize a window to 400x300px
xwin.resize(400, 300)
#Resize a terminal window to 100 rows and 100 columns
xtermwin.resize(100, 100, true)

Remarks

This has no effect on maximized winwows.



588
589
590
591
592
593
594
595
# File 'lib/xdo/xwindow.rb', line 588

def resize(width, height, use_hints = false, sync = true)
  err = ""
  opts = []
  opts << "--usehints" if use_hints
  opts << "--sync" if sync
  Open3.popen3("#{XDo::XDOTOOL} windowsize #{opts.join(" ")} #{@id} #{width} #{height}"){|stdin, stdout, stderr| err << stderr.read}
  Kernel.raise(XDo::XError, err) unless err.empty?
end

#sizeObject

The size of the window.

Return value

A two-element array of form [width, height].

Raises

XError

Error executing xwininfo.

Example

p xwin.size #=> [1280, 948]


845
846
847
848
849
850
851
852
853
854
# File 'lib/xdo/xwindow.rb', line 845

def size
  out = ""
  err = ""
  Open3.popen3("#{XDo::XWININFO} -id #{@id}"){|stdin, stdout, stderr| out << stdout.read; err << stderr.read}
  out = out.strip.lines.to_a
  Kernel.raise(XDo::XError, err) unless err.empty?
  width = out[6].match(/:\s+(\d+)/)[1]
  height = out[7].match(/:\s+(\d+)/)[1]
  [width.to_i, height.to_i]
end

#titleObject

The title of the window or nil if it doesn’t have a title.

Return value

The window’s title, encoded as UTF-8, or nil if the window doesn’t have a title.

Raises

XError

Error executing xwininfo.

Example

p xwin.title #=> "xwindow.rb SciTE"


786
787
788
789
790
791
792
793
794
795
796
797
798
799
# File 'lib/xdo/xwindow.rb', line 786

def title
  err = ""
  out = ""
  if @id == XWindow.root_id #This is the root window
    return "(the root window)"
  elsif @id.zero?
    return "(NULL window)"
  else
    Open3.popen3("#{XDo::XWININFO} -id #{@id}"){|stdin, stdout, stderr| out << stdout.read; err << stderr.read}
  end
  Kernel.raise(XDo::XError, err) unless err.empty?
  title = out.strip.lines.to_a[0].match(/"(.*)"/)[1] rescue Kernel.raise(XDo::XError, "No window with ID #{@id} found!")
  return title #Kann auch nil sein, dann ist das Fenster namenlos.
end

#to_iObject

Returns the window’s internal ID.

Return value

An integer describing the window’s internal ID.

Example

p xwin.to_i #=> 29361095


955
956
957
# File 'lib/xdo/xwindow.rb', line 955

def to_i
  @id
end

#to_sObject

Returns a window’s title.

Return value

The window’s title.

Example

p xwin.to_s #=> "xwindow.rb * SciTE"


964
965
966
# File 'lib/xdo/xwindow.rb', line 964

def to_s
  title
end

#unfocus(sync = true) ⇒ Object

The window loses the input focus by setting it to an invalid window. Parameters

sync

(true) If true, this method blocks until the focus has been set to nothing.

Return value

Undefined.

Example

xwin.focus
xwin.unfocus


646
647
648
# File 'lib/xdo/xwindow.rb', line 646

def unfocus(sync = true)
  XDo::XWindow.unfocus(sync)
end

#unmap(sync = true) ⇒ Object

Unmap a window from the screen (make it invisible).

Parameters

sync

(true) If true, this method blocks until the window has been unmapped.

Return value

Undefined.

Raises

XError

Error executing xdotool.

Example

xwin.unmap


677
678
679
680
681
682
683
# File 'lib/xdo/xwindow.rb', line 677

def unmap(sync = true)
  err = ""
  opts = []
  opts << "--sync" if sync
  Open3.popen3("#{XDo::XDOTOOL} windowunmap #{opts.join(" ")} #{@id}"){|stdin, stdout, stderr| err << stderr.read}
  Kernel.raise(XDo::XError, err) unless err.empty?
end

#visible?Boolean

true if the window is mapped to the screen.

Return value

nil if the window is not mapped, an integer value otherwise.

Raises

XError

Error executing xwininfo.

Example

p xwin.visible? #=> 470
xwin.unmap
p xwin.visible? #=> nil

Returns:

  • (Boolean)


865
866
867
868
869
870
871
872
# File 'lib/xdo/xwindow.rb', line 865

def visible?
  err = ""
  out = ""
  Open3.popen3("#{XDo::XWININFO} -id #{@id}"){|stdin, stdout, stderr| out << stdout.read; err << stderr.read}
  out = out.strip
  Kernel.raise(XDo::XError, err) unless err.empty?
  return out =~ /IsViewable/
end

#zero?Boolean

true if the internal ID is zero.

Return value

true or false.

Example

p xwin.zero? #=> false

Returns:

  • (Boolean)


973
974
975
# File 'lib/xdo/xwindow.rb', line 973

def zero?
  @id.zero?
end