Class: XDo::XWindow
- Inherits:
-
Object
- Object
- XDo::XWindow
- Extended by:
- Open3
- Includes:
- Open3
- 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 Jaunty) 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.
Many methods accept a name
parameter; be aware that this name is not the whole name of a window, but a pattern to match. So, if you pass in “edit”, it will even match “gedit”. xdotool
handles that parameter with C style regexps.
The opt
parameter of many methods is a hash that can have the following keys:
Key | Effect if true
=============+====================================
:title | Window titles are searched.
-------------+------------------------------------
:name | Window names are searched.
-------------+------------------------------------
:class | Window classes are searched.
-------------+------------------------------------
:onlyvisible | Only visible windows are searched.
The default values for them depend on the method you want to use. See the method’s argument list to find out if a parameter is set to true or, if it isn’t mentioned, to nil.
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
-
#id ⇒ Object
readonly
The internal ID of the window.
Class Method Summary collapse
-
.active_window ⇒ Object
Returns the internal ID of the currently focused window.
-
.desktop ⇒ Object
Output the number of the active desktop.
-
.desktop=(num) ⇒ Object
Change the view to desktop
num
. -
.desktop_name ⇒ Object
Name of the desktop window.
-
.desktop_name=(name) ⇒ Object
Set this to the name of your desktop window.
-
.desktop_num ⇒ Object
Get the number of working desktops.
-
.desktop_num=(num) ⇒ Object
Set the number of working desktops.
-
.exists?(name, opts = {title: true, name: true, :class => true}) ⇒ Boolean
Checks if a window whose name matches
name
exists. -
.focus_desktop ⇒ Object
(also: activate_desktop)
Activate the desktop.
-
.focused_window(notice_childs = false) ⇒ Object
Returns the internal ID of the currently focused window.
-
.from_active ⇒ Object
Creates a XWindow by calling active_window.
-
.from_focused(notice_childs = false) ⇒ Object
Creates a XWindow by calling focused_window with the given parameter.
-
.from_name(name, opts = {title: true, name: true, :class => true}) ⇒ Object
Creates a XWindow by calling search with the given parameters.
-
.id_exists?(id) ⇒ Boolean
Returns true if the given window ID exists, false otherwise.
-
.minimize ⇒ Object
Minimizes the active window.
-
.search(name, opts = {title: true, name: true, :class => true}) ⇒ Object
Search for a window name to get the internal ID of a window.
-
.toggle_maximize ⇒ Object
Maximize or normalize the active window if already maximized.
-
.toggle_minimize_all ⇒ Object
Minimize all windows (or restore, if already) by sending [CTRL]
[ALT]
[D]. -
.wait_for_close(name, opts = {title: true, name: true, :class => true, :onlyvisible => true}) ⇒ Object
Waits for a window to close.
-
.wait_for_window(name, opts = {title: true, name: true, :class => true, :onlyvisible => true}) ⇒ Object
Waits for a window name to exist and returns the ID of that window.
Instance Method Summary collapse
-
#abs_position ⇒ Object
(also: #position)
The absolute position of the window on the screen.
-
#activate ⇒ Object
Activate a window.
-
#close ⇒ Object
Closes a window by activating it and then sending [ALT] + [F4].
-
#close!(timeout = 2) ⇒ Object
More aggressive variant of #close.
-
#desktop ⇒ Object
Get the desktop the window is on.
-
#desktop=(num) ⇒ Object
Move a window to a desktop.
-
#exists? ⇒ Boolean
Returns true if the window exists.
-
#focus ⇒ Object
Set the input focus to the window (but don’t bring it to the front).
-
#initialize(id) ⇒ XWindow
constructor
Creates a new XWindow object from an internal ID.
-
#inspect ⇒ Object
Human-readable output of form <XDo::XWindow: “title” (window_id)>.
-
#kill! ⇒ Object
Kills the process that runs a window.
-
#map ⇒ Object
Map a window to the screen (make it visible).
-
#move(x, y) ⇒ Object
Moves a window.
-
#raise ⇒ Object
Bring a window to the front (but don’t give it the input focus).
-
#rel_position ⇒ Object
The position of the window relative to it’s parent window.
-
#resize(width, height, use_hints = false) ⇒ Object
Set the size of a window.
-
#size ⇒ Object
The size of the window.
-
#title ⇒ Object
The title of the window or nil if it doesn’t have a title.
-
#unfocus ⇒ Object
The window loses the input focus by setting it to the desktop.
-
#unmap ⇒ Object
Unmap a window from the screen (make it invisible).
-
#visible? ⇒ Boolean
true if the window is mapped to the screen.
Constructor Details
#initialize(id) ⇒ XWindow
Creates a new XWindow object from an internal ID. See the XWindow class methods.
218 219 220 |
# File 'lib/xdo/xwindow.rb', line 218 def initialize(id) @id = id.to_i end |
Instance Attribute Details
#id ⇒ Object (readonly)
The internal ID of the window.
48 49 50 |
# File 'lib/xdo/xwindow.rb', line 48 def id @id end |
Class Method Details
.active_window ⇒ Object
Returns the internal ID of the currently focused window. This method is more reliable than focused_window. Part of the EWMH standard ACTIVE_WINDOW.
112 113 114 115 116 117 118 |
# File 'lib/xdo/xwindow.rb', line 112 def active_window err = "" out = "" popen3("#{XDo::XDOTOOL} getactivewindow"){|stdin, stdout, stderr| out = stdout.read; err = stderr.read} raise(XDo::XError, err) unless err.empty? return Integer(out) end |
.desktop ⇒ Object
Output the number of the active desktop. Part of the EWMH standard CURRENT_DESKTOP.
150 151 152 153 154 155 156 |
# File 'lib/xdo/xwindow.rb', line 150 def desktop err = "" out = "" 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
. Part of the EWMH standard CURRENT_DESKTOP.
141 142 143 144 145 146 |
# File 'lib/xdo/xwindow.rb', line 141 def desktop=(num) err = "" popen3("#{XDo::XDOTOOL} set_desktop #{num}"){|stdin, stdout, stderr| err << stderr.read} raise(XDo::XError, err) unless err.empty? num end |
.desktop_name ⇒ Object
Name of the desktop window. Default is “x-nautilus-desktop”.
182 183 184 |
# File 'lib/xdo/xwindow.rb', line 182 def desktop_name @desktop_name ||= "x-nautilus-desktop" end |
.desktop_name=(name) ⇒ Object
Set this to the name of your desktop window.
177 178 179 |
# File 'lib/xdo/xwindow.rb', line 177 def desktop_name=(name) @desktop_name = name end |
.desktop_num ⇒ Object
Get the number of working desktops. Part of the EWMH standard WM_DESKTOP.
131 132 133 134 135 136 137 |
# File 'lib/xdo/xwindow.rb', line 131 def desktop_num err = "" out = "" 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. Part of the EWMH standard WM_DESKTOP.
122 123 124 125 126 127 |
# File 'lib/xdo/xwindow.rb', line 122 def desktop_num=(num) err = "" 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 = {title: true, name: true, :class => true}) ⇒ Boolean
Checks if a window whose name matches name
exists. Think about passing :onlyvisible in the opt
hash.
54 55 56 57 58 59 60 |
# File 'lib/xdo/xwindow.rb', line 54 def exists?(name, opts = {title: true, name: true, :class => true}) begin !search(name, opts).empty? rescue false end end |
.focus_desktop ⇒ Object Also known as: activate_desktop
Activate the desktop
187 188 189 190 191 |
# File 'lib/xdo/xwindow.rb', line 187 def focus_desktop desktop = from_name(desktop_name) desktop.focus desktop.activate end |
.focused_window(notice_childs = false) ⇒ Object
Returns the internal ID of the currently focused window. If the notice_childs
parameter is true, also childwindows are noticed. This method may find an invisible window, see active_window for a more reliable method.
101 102 103 104 105 106 107 |
# File 'lib/xdo/xwindow.rb', line 101 def focused_window(notice_childs = false) err = "" out = "" popen3("#{XDo::XDOTOOL} getwindowfocus #{notice_childs ? "-f" : ""}"){|stdin, stdout, stderr| out << stdout.read; err << stderr.read} raise(XDo::XError, err) unless err.empty? return out.to_i end |
.from_active ⇒ Object
Creates a XWindow by calling active_window.
172 173 174 |
# File 'lib/xdo/xwindow.rb', line 172 def from_active new(active_window) end |
.from_focused(notice_childs = false) ⇒ Object
Creates a XWindow by calling focused_window with the given parameter.
167 168 169 |
# File 'lib/xdo/xwindow.rb', line 167 def from_focused(notice_childs = false) new(focused_window(notice_childs)) end |
.from_name(name, opts = {title: true, name: true, :class => true}) ⇒ Object
Creates a XWindow by calling search with the given parameters. The window is created from the first ID found.
160 161 162 163 164 |
# File 'lib/xdo/xwindow.rb', line 160 def from_name(name, opts = {title: true, name: true, :class => true}) ids = search(name, opts) raise(XDo::XError, "The window '#{name}' wasn't found!") if ids.empty? new(ids.first) end |
.id_exists?(id) ⇒ Boolean
Returns true if the given window ID exists, false otherwise.
63 64 65 66 67 68 |
# File 'lib/xdo/xwindow.rb', line 63 def id_exists?(id) err = "" popen3("#{XDo::XWININFO} -id #{id}"){|stdin, stdout, stderr| err << stderr.read} return false unless err.empty? return true end |
.minimize ⇒ Object
Minimizes the active window. There’s no way to restore a specific minimized window. Available after requireing “xdo/keyboard”.
203 204 205 206 |
# File 'lib/xdo/xwindow.rb', line 203 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 |
.search(name, opts = {title: true, name: true, :class => true}) ⇒ Object
Search for a window name to get the internal ID of a window. Return value is an array containing all found IDs or an empty array if none is found.
88 89 90 91 92 93 94 95 |
# File 'lib/xdo/xwindow.rb', line 88 def search(name, opts = {title: true, name: true, :class => true}) cmd = "#{XDo::XDOTOOL} search " opts.each_pair{|key, value| cmd << "--#{key} " if value} cmd << '"' << name << '"' #Error wird nicht behandelt, weil im Fehlerfall einfach nur ein leeres Array zurückkommen soll out = `#{cmd}` out.lines.to_a.collect{|l| l.strip.to_i} end |
.toggle_maximize ⇒ Object
Maximize or normalize the active window if already maximized. Available after requireing “xdo/keyboard”.
210 211 212 213 |
# File 'lib/xdo/xwindow.rb', line 210 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_all ⇒ Object
Minimize all windows (or restore, if already) by sending [CTRL][ALT]
[D]. Available after requireing “xdo/keyboard”.
196 197 198 199 |
# File 'lib/xdo/xwindow.rb', line 196 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 |
.wait_for_close(name, opts = {title: true, name: true, :class => true, :onlyvisible => true}) ⇒ Object
Waits for a window to close. If the window does not exists when calling wait_for_close
, the method returns immediately.
80 81 82 83 |
# File 'lib/xdo/xwindow.rb', line 80 def wait_for_close(name, opts = {title: true, name: true, :class => true, :onlyvisible => true}) loop{break if !exists?(name, opts);sleep(0.5)} nil end |
.wait_for_window(name, opts = {title: true, name: true, :class => true, :onlyvisible => true}) ⇒ Object
Waits for a window name to exist and returns the ID of that window. Returns immediately if the window does already exist.
72 73 74 75 76 |
# File 'lib/xdo/xwindow.rb', line 72 def wait_for_window(name, opts = {title: true, name: true, :class => true, :onlyvisible => true}) loop{break if exists?(name, opts);sleep(0.5)} sleep 1 #To ensure it's really there search(name, opts).first end |
Instance Method Details
#abs_position ⇒ Object Also known as: position
The absolute position of the window on the screen.
315 316 317 318 319 320 321 322 323 324 |
# File 'lib/xdo/xwindow.rb', line 315 def abs_position out = "" err = "" 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 ⇒ Object
Activate a window. That is, bring it to top and give it the input focus. Part of the EWMH standard ACTIVE_WINDOW.
280 281 282 283 284 |
# File 'lib/xdo/xwindow.rb', line 280 def activate err = "" popen3("#{XDo::XDOTOOL} windowactivate #{@id}"){|stdin, stdout, stderr| err << stderr.read} Kernel.raise(XDo::XError, err) unless err.empty? end |
#close ⇒ Object
Closes a window by activating it and then sending [ALT] + [F4]. A program could ask to save data. Use #kill! to kill the process running the window. Available after requireing “xdo/keyboard”
370 371 372 373 374 375 376 377 |
# File 'lib/xdo/xwindow.rb', line 370 def close Kernel.raise(NotImplementedError, "You have to require 'xdo/keyboard' before you can use #{__method__}!") unless defined? XDo::Keyboard activate sleep 0.5 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!. Available after requireing “xdo/keyboard”.
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 |
# File 'lib/xdo/xwindow.rb', line 384 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! else return end else return end end |
#desktop ⇒ Object
Get the desktop the window is on. Part of the EWMH standard CURRENT_DESKTOP.
296 297 298 299 300 301 302 |
# File 'lib/xdo/xwindow.rb', line 296 def desktop err = "" out = "" 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. Part of the EWMH standard CURRENT_DESKTOP.
288 289 290 291 292 |
# File 'lib/xdo/xwindow.rb', line 288 def desktop=(num) err = "" 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.
362 363 364 |
# File 'lib/xdo/xwindow.rb', line 362 def exists? XDo::XWindow.exists?(@id) end |
#focus ⇒ Object
Set the input focus to the window (but don’t bring it to the front).
245 246 247 248 249 |
# File 'lib/xdo/xwindow.rb', line 245 def focus err = "" popen3("#{XDo::XDOTOOL} windowfocus #{@id}"){|stdin, stdout, stderr| err << stderr.read} Kernel.raise(XDo::XError, err) unless err.empty? end |
#inspect ⇒ Object
Human-readable output of form
<XDo::XWindow: "title" (window_id)>
224 225 226 |
# File 'lib/xdo/xwindow.rb', line 224 def inspect %Q|<XDo::XWindow: "#{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.
406 407 408 409 410 411 412 |
# File 'lib/xdo/xwindow.rb', line 406 def kill! out = "" err = "" 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 ⇒ Object
Map a window to the screen (make it visible).
257 258 259 260 261 |
# File 'lib/xdo/xwindow.rb', line 257 def map err = "" popen3("#{XDo::XDOTOOL} windowmap #{@id}"){|stdin, stdout, stderr| err << stderr.read} Kernel.raise(XDo::XError, err) unless err.empty? end |
#move(x, y) ⇒ Object
Moves a window. xdotool
is not really exact with the coordinates, the window will be within a range of +-10 pixels.
238 239 240 241 242 |
# File 'lib/xdo/xwindow.rb', line 238 def move(x, y) err = "" popen3("#{XDo::XDOTOOL} windowmove #{@id} #{x} #{y}"){|stdin, stdout, stderr| err << stderr.read} Kernel.raise(XDo::XError, err) unless err.empty? end |
#raise ⇒ Object
Bring a window to the front (but don’t give it the input focus). Not implemented in all window managers.
272 273 274 275 276 |
# File 'lib/xdo/xwindow.rb', line 272 def raise err = "" popen3("#{XDo::XDOTOOL} windowraise #{@id}"){|stdin, stdout, stderr| err << stderr.read} Kernel.raise(XDo::XError, err) unless err.empty? end |
#rel_position ⇒ Object
The position of the window relative to it’s parent window.
328 329 330 331 332 333 334 335 336 337 |
# File 'lib/xdo/xwindow.rb', line 328 def rel_position out = "" err = "" 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) ⇒ Object
Set the size of a window. This has no effect on maximized winwows.
229 230 231 232 233 234 |
# File 'lib/xdo/xwindow.rb', line 229 def resize(width, height, use_hints = false) err = "" cmd = "#{XDo::XDOTOOL} windowsize #{use_hints ? "--usehints " : ""}#{@id} #{width} #{height}" popen3("#{cmd}"){|stdin, stdout, stderr| err << stderr.read} Kernel.raise(XDo::XError, err) unless err.empty? end |
#size ⇒ Object
The size of the window.
340 341 342 343 344 345 346 347 348 349 |
# File 'lib/xdo/xwindow.rb', line 340 def size out = "" err = "" 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 |
#title ⇒ Object
The title of the window or nil if it doesn’t have a title.
305 306 307 308 309 310 311 312 |
# File 'lib/xdo/xwindow.rb', line 305 def title err = "" out = "" popen3("#{XDo::XWININFO} -id #{@id}"){|stdin, stdout, stderr| out << stdout.read; err << stderr.read} 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 |
#unfocus ⇒ Object
The window loses the input focus by setting it to the desktop.
252 253 254 |
# File 'lib/xdo/xwindow.rb', line 252 def unfocus XDo::XWindow.focus_desktop end |
#unmap ⇒ Object
Unmap a window from the screen (make it invisible).
264 265 266 267 268 |
# File 'lib/xdo/xwindow.rb', line 264 def unmap err = "" popen3("#{XDo::XDOTOOL} windowunmap #{@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.
352 353 354 355 356 357 358 359 |
# File 'lib/xdo/xwindow.rb', line 352 def visible? err = "" out = "" 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? return out[17].match(/:\s+(\w+)/)[1] == "IsViewable" ? true : false end |