xdo 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/DEPRECATE.rdoc +11 -0
- data/HISTORY.rdoc +33 -0
- data/README.rdoc +53 -0
- data/VERSION +1 -0
- data/bin/xinfo.rb +155 -0
- data/lib/xdo.rb +37 -0
- data/lib/xdo/clipboard.rb +208 -0
- data/lib/xdo/drive.rb +125 -0
- data/lib/xdo/keyboard.rb +381 -0
- data/lib/xdo/mouse.rb +251 -0
- data/lib/xdo/simulatable.rb +89 -0
- data/lib/xdo/xwindow.rb +1006 -0
- data/samples/full_demo.rb +189 -0
- data/samples/mouse.rb +27 -0
- data/test/test_clipboard.rb +49 -0
- data/test/test_drive.rb +24 -0
- data/test/test_keyboard.rb +111 -0
- data/test/test_mouse.rb +29 -0
- data/test/test_xwindow.rb +97 -0
- metadata +115 -0
data/DEPRECATE.rdoc
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
=Deprecations
|
2
|
+
The following method uses are _deprecated_ and will be removed in the next minor version bump. They show a warning if you use them unless otherwise stated.
|
3
|
+
|
4
|
+
* XWindow.desktop_name= is obsolete now and has noo effect anymore.
|
5
|
+
* XWindow.desktop_name is obsolete now. It always returns "x-nautilus-desktop".
|
6
|
+
* XWindow.focus_desktop has been deprecated. Use XWindow.unfocus instead.
|
7
|
+
* All Clipboard module methods take a hash in order to specify which clipboards to interact with now take the symbols directly via a rest argument.
|
8
|
+
* All Mouse module methods that took constant values now accept symbols. The old behaviour is deprecated now.
|
9
|
+
* All XWindow class methods that take a hash in order to specify which windows to search now take the symbols directly via a rest argument.
|
10
|
+
* All XWindow class methods that take a string as the window to search for are now accepting Regular Expressions. That means, in later version you have to pass in a regexp if you don't want to look for an entire title at once, i.e. <tt>"edit"</tt> won't find a "gedit" window, but <tt>/edit/</tt> will. <b>This doesn't show a warning. </b>
|
11
|
+
* XWindow.from_name has been deprecated. The old functionality (i.e. the ability to specify all search parameters) is now provided by the XWindow.from_search method. XWindow.from_name will be used as an alias for XWindow.from_title in the next version.
|
data/HISTORY.rdoc
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
=History of the xdo gem
|
2
|
+
This file shows the history of the xdo gem
|
3
|
+
from it's very beginning. Important changes in the
|
4
|
+
API are marked <b>bold</b>. Bugfixes are <i>italic</i>.
|
5
|
+
|
6
|
+
==0.0.4
|
7
|
+
* <b>Several methods now accept a +sync+ parameter wrapping +xdotool+'s <tt>--sync</tt> option. </b>
|
8
|
+
* <b>Added XWindow.unfocus</b>
|
9
|
+
* <b>Added XWindow.root_id</b>
|
10
|
+
* <b>Added XWindow.from_root</b>
|
11
|
+
* <b>Added XWindow.from_null</b>
|
12
|
+
* Removed the internal SmallScanner class. We're now using StringScanner directly.
|
13
|
+
* All methods in the Mouse module now accept symbols for the +button+ parameter.
|
14
|
+
* <i>XWindow#exists? aways returned false. This has been fixed.</i>
|
15
|
+
* <i>XWindow#visible? always returned false. This has been fixed.</i>
|
16
|
+
* <b>Added XWindow#to_i and XWindow#to_s.</b>
|
17
|
+
* <b>Added XWindow#zero? and XWindow#nonzero?.</b>
|
18
|
+
* All methods in the Keyboard module that accept a +w_id+ parameter now can take XWindow objects.
|
19
|
+
* Removed Keyboard.sequence_escape.
|
20
|
+
* Several deprecations. See DEPRECATE.rdoc.
|
21
|
+
* <b>Added XWindow.from_title.</b>
|
22
|
+
|
23
|
+
==0.0.3
|
24
|
+
* <i>Some XWindow instance methods (like #close!) showed wrong error messages due to the redundance of Kernel#raise with XWindow#raise. This has been fixed. </i>
|
25
|
+
* If run alone, the "test_xwindow.rb" test file failed with obscure errors. Fixed.
|
26
|
+
|
27
|
+
==0.0.2
|
28
|
+
* Replaced fork{system("gedit")} in full_demo.rb with spawn("gedit")
|
29
|
+
* Removed "require 'pp'" from keyboard.rb
|
30
|
+
* <b>Added the Simulatable mixin</b>
|
31
|
+
* <b>Corrected window id usage for the XDo::Keyboard module</b>
|
32
|
+
* Added a test for the window id usage
|
33
|
+
* Made the test-unit gem a development dependency
|
data/README.rdoc
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--
|
2
|
+
This file is part of Xdo.
|
3
|
+
Copyright © 2009, 2010 Marvin Gülker
|
4
|
+
Initia in potestate nostra sunt, de eventu fortuna iudicat.
|
5
|
+
++
|
6
|
+
=XDo
|
7
|
+
XDo is a library to simulate keyboard and mouse input and manipulating windows on the X server.
|
8
|
+
It's wrapped around the command-line tools xdotool[http://www.semicomplete.com/projects/xdotool/],
|
9
|
+
xsel[http://linux.die.net/man/1/xsel], xwininfo[http://linux.die.net/man/1/xwininfo], eject[http://linux.die.net/man/1/eject] and xkill[http://linux.die.net/man/1/xkill],
|
10
|
+
so you will need to have them installed if you want to use Xdo (even if xwininfo, eject and xkill are usually already installed).
|
11
|
+
If not, try to install them via your favourite packaging manager.
|
12
|
+
After they're installed, install XDo via RubyGems:
|
13
|
+
sudo gem install xdo
|
14
|
+
==Usage
|
15
|
+
#Require some of XDo's files
|
16
|
+
require "xdo/keyboard"
|
17
|
+
require "xdo/mouse"
|
18
|
+
require "xdo/xwindow"
|
19
|
+
#Move the cursor
|
20
|
+
XDo::Mouse.move(100, 100)
|
21
|
+
#Simulate text (with special escape sequences!)
|
22
|
+
XDo::Keyboard.simulate("This is{TAB}text.")
|
23
|
+
#Some sequences can be shortened:
|
24
|
+
XDo::Keyboard.simulate("This ist\ttext.")
|
25
|
+
#And this will move a window containing the string "gedit",
|
26
|
+
#unless it's maximized.
|
27
|
+
win = XDo::XWindow.from_title(/gedit/)
|
28
|
+
win.move(200, 200)
|
29
|
+
==Files
|
30
|
+
You can require the following files in your projects:
|
31
|
+
* xdo/clipboard: Clipboard access
|
32
|
+
* xdo/drive: Get control of CD/DVD devices
|
33
|
+
* xdo/keyboard: Pretty self-explaining
|
34
|
+
* xdo/mouse: Automate the mouse
|
35
|
+
* xdo/xwindow: Manipulate windows in various ways
|
36
|
+
As an helpful extra, I created an executable ruby file "xinfo.rb". Thanks to RubyGems,
|
37
|
+
you can start this GUI tool right from the command line by typing:
|
38
|
+
xinfo.rb
|
39
|
+
It's by far not perfect, maybe not even good, but I think it can be useful sometimes
|
40
|
+
(you will need to have wxRuby installed, try <tt>sudo gem install wxruby-ruby19</tt>).
|
41
|
+
If you're looking for a more professional program, try the "X window information" tool.
|
42
|
+
==Notes
|
43
|
+
* If your +xdotool+ seems to reject the --window option, you are not using the current version. Try building the newest one from the source.
|
44
|
+
* I recommand the "X window information" tool to get infos about your windows if you aren't satisfied by the xinfo.rb shipped with this package.
|
45
|
+
==Fairly incomplete
|
46
|
+
* I'm sure there are several things I didn't notice that can be automated somehow. If you know about, email me! Please add a description of the possibilities and a sample script.
|
47
|
+
* Another interesting thing are the samples. There are many Linux distrubitions out there, and even many of them rely on X. I cannot test with another than a recent Ubuntu machine, but if you want to contribute and send samples for another OS, I want to encourage you to - I surely won't reject your work. :-)
|
48
|
+
==License/Copyright
|
49
|
+
Copyright © 2009, 2010 Marvin Gülker
|
50
|
+
This library is free software; you may redistribute it and/or modify it
|
51
|
+
under the terms of Ruby's license (see http://www.ruby-lang.org/en/LICENSE.txt).
|
52
|
+
You can contact me at sutniuq ät gmx Dot net.
|
53
|
+
Initia in potestate nostra sunt, de eventu fortuna iudicat.
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.4
|
data/bin/xinfo.rb
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#Encoding: UTF-8
|
3
|
+
#This file is part of Xdo.
|
4
|
+
#Copyright © 2009, 2010 Marvin Gülker
|
5
|
+
# Initia in potestate nostra sunt, de eventu fortuna iudicat.
|
6
|
+
#
|
7
|
+
#This program displays information about the currently selected window
|
8
|
+
#and the mouse. The displayed infos are updated every 1/2 second,
|
9
|
+
#but set XInfo::UPDATE_TIME to another value if you'd like to change that.
|
10
|
+
|
11
|
+
require "logger"
|
12
|
+
require "wx"
|
13
|
+
|
14
|
+
require_relative("../lib/xdo/xwindow")
|
15
|
+
require_relative("../lib/xdo/mouse")
|
16
|
+
|
17
|
+
#Class that retrieves the information of windows.
|
18
|
+
class InfoGetter
|
19
|
+
|
20
|
+
attr_reader :act_win
|
21
|
+
attr_reader :cursorpos
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@act_win = XDo::XWindow.from_active
|
25
|
+
@cursorpos = XDo::Mouse.position
|
26
|
+
end
|
27
|
+
|
28
|
+
def update
|
29
|
+
@act_win = XDo::XWindow.from_active
|
30
|
+
@cursorpos = XDo::Mouse.position
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
class XInfoFrame < Wx::Frame
|
36
|
+
include Wx
|
37
|
+
|
38
|
+
#Time intervall of updating the infos, in milliseconds.
|
39
|
+
#Default is 500, which is 1/2 second.
|
40
|
+
UPDATE_TIME = 500
|
41
|
+
|
42
|
+
def initialize(parent = nil)
|
43
|
+
super(parent, title: "XInfo", size: Size.new(300, 400), style: DEFAULT_FRAME_STYLE | STAY_ON_TOP)
|
44
|
+
self.background_colour = NULL_COLOUR
|
45
|
+
THE_APP.log.debug("Creating controls")
|
46
|
+
create_controls
|
47
|
+
THE_APP.log.debug("Setting up timer")
|
48
|
+
create_updater
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def create_controls
|
54
|
+
StaticText.new(self, -1, "Title of active window: ", Point.new(20, 20))
|
55
|
+
@title = TextCtrl.new(self, pos: Point.new(20, 50), size: Size.new(260, 24), style: TE_READONLY)
|
56
|
+
StaticText.new(self, -1, "ID of active window: ", Point.new(20, 80))
|
57
|
+
@id = TextCtrl.new(self, -1, "", Point.new(20, 110), Size.new(260, 24), TE_READONLY)
|
58
|
+
StaticText.new(self, -1, "Absoloute and relative upper-left coords: ", Point.new(20,140))
|
59
|
+
StaticText.new(self, -1, "Abs: ", Point.new(20, 173))
|
60
|
+
@abs_xy = TextCtrl.new(self, -1, "", Point.new(60, 170), Size.new(70, 24), TE_READONLY)
|
61
|
+
StaticText.new(self, -1, "Rel: ", Point.new(150, 173))
|
62
|
+
@rel_xy = TextCtrl.new(self, -1, "", Point.new(190, 170), Size.new(70, 24), TE_READONLY)
|
63
|
+
StaticText.new(self, -1, "Size: ", Point.new(20, 200))
|
64
|
+
StaticText.new(self, -1, "Width: ", Point.new(20, 233))
|
65
|
+
@width = TextCtrl.new(self, -1, "", Point.new(65, 230), Size.new(70, 24), TE_READONLY)
|
66
|
+
StaticText.new(self, -1, "Height: ", Point.new(150, 233))
|
67
|
+
@height = TextCtrl.new(self, -1, "", Point.new(200, 230), Size.new(70, 24), TE_READONLY)
|
68
|
+
|
69
|
+
StaticText.new(self, -1, "Mouse position: ", Point.new(20, 300))
|
70
|
+
StaticText.new(self, -1, "X: ", Point.new(20, 333))
|
71
|
+
@x = TextCtrl.new(self, -1, "", Point.new(60, 330), Size.new(70, 24), TE_READONLY)
|
72
|
+
StaticText.new(self, -1, "Y: ", Point.new(150, 333))
|
73
|
+
@y = TextCtrl.new(self, -1, "", Point.new(190, 330), Size.new(70, 24), TE_READONLY)
|
74
|
+
end
|
75
|
+
|
76
|
+
def create_updater
|
77
|
+
@updater = InfoGetter.new
|
78
|
+
Timer.every(UPDATE_TIME) do
|
79
|
+
begin
|
80
|
+
@updater.update
|
81
|
+
@title.value = @updater.act_win.title
|
82
|
+
@id.value = @updater.act_win.id.inspect
|
83
|
+
@abs_xy.value = @updater.act_win.abs_position.join(", ")
|
84
|
+
@rel_xy.value = @updater.act_win.rel_position.join(", ")
|
85
|
+
ary = @updater.act_win.size
|
86
|
+
@width.value = ary[0].inspect
|
87
|
+
@height.value = ary[1].inspect
|
88
|
+
end
|
89
|
+
|
90
|
+
curpos = @updater.cursorpos
|
91
|
+
@x.value = curpos[0].inspect
|
92
|
+
@y.value = curpos[1].inspect
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
#Main App object of this program.
|
99
|
+
class XInfo < Wx::App
|
100
|
+
include Wx
|
101
|
+
|
102
|
+
#Logger.
|
103
|
+
attr_reader :log
|
104
|
+
|
105
|
+
def on_init
|
106
|
+
@log = Logger.new($stdout)
|
107
|
+
@log.level = Logger::INFO unless $VERBOSE || $DEBUG
|
108
|
+
@log.info("Started")
|
109
|
+
@log.debug "Creating main window"
|
110
|
+
@mainwindow = XInfoFrame.new
|
111
|
+
@mainwindow.show
|
112
|
+
end
|
113
|
+
|
114
|
+
def on_run
|
115
|
+
super
|
116
|
+
rescue => e
|
117
|
+
@log.fatal(e.class.name)
|
118
|
+
@log.fatal(e.message)
|
119
|
+
e.backtrace.each{|trace| @log.fatal(trace)}
|
120
|
+
message = "A #{e.class} occured: #{e.message} \n\nBacktrace: \n\n#{e.backtrace.join("\n")}"
|
121
|
+
message << "\n\nIf you want to contact me about the error, send an email to sutniuq ät gmx Dot net."
|
122
|
+
msgbox = MessageDialog.new(@mainwindow, message, $!.class.name, OK | ICON_ERROR)
|
123
|
+
msgbox.show_modal
|
124
|
+
raise
|
125
|
+
end
|
126
|
+
|
127
|
+
def on_exit
|
128
|
+
super
|
129
|
+
@log.info("Finished.")
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
if ARGV.include?("-h") or ARGV.include?("--help")
|
135
|
+
puts "This is xinfo.rb, from xdo #{XDo::VERSION}."
|
136
|
+
puts "xinfo.rb is a tool for inspecting GUI windows on X."
|
137
|
+
puts
|
138
|
+
puts "Copyright © 2010 Marvin Gülker"
|
139
|
+
puts "Licensed under the same terms as Ruby."
|
140
|
+
puts "You can find Ruby's license at http://www.ruby-lang.org/en/LICENSE.txt."
|
141
|
+
puts
|
142
|
+
puts "xinfo.rb doesn't understand many command-line options."
|
143
|
+
puts "There's -h for this message, -V for verbose output"
|
144
|
+
puts "and -d for debugging. -v shows XDo's version."
|
145
|
+
exit
|
146
|
+
elsif ARGV.include?("-v") or ARGV.include?("--version")
|
147
|
+
puts "This is xinfo.rb, from xdo #{XDo::VERSION}."
|
148
|
+
exit
|
149
|
+
end
|
150
|
+
|
151
|
+
$VERBOSE = true if ARGV.include?("-V")
|
152
|
+
$DEBUG = true if ARGV.include?("-d")
|
153
|
+
|
154
|
+
x = XInfo.new
|
155
|
+
x.main_loop
|
data/lib/xdo.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#Encoding: UTF-8
|
2
|
+
#This file is part of Xdo.
|
3
|
+
#Copyright © 2009 Marvin Gülker
|
4
|
+
# Initia in potestate nostra sunt, de eventu fortuna iudicat.
|
5
|
+
|
6
|
+
require "open3"
|
7
|
+
require "strscan"
|
8
|
+
|
9
|
+
#The namespace of this library.
|
10
|
+
module XDo
|
11
|
+
|
12
|
+
#The command to start xdotool.
|
13
|
+
XDOTOOL = "xdotool"
|
14
|
+
|
15
|
+
#The command to start xsel.
|
16
|
+
XSEL = "xsel"
|
17
|
+
|
18
|
+
#The command to start xwininfo.
|
19
|
+
XWININFO = "xwininfo"
|
20
|
+
|
21
|
+
#The command to start xkill.
|
22
|
+
XKILL = "xkill"
|
23
|
+
|
24
|
+
#The command to start eject.
|
25
|
+
EJECT = "eject"
|
26
|
+
|
27
|
+
#The version of this library.
|
28
|
+
VERSION = File.read(File.join(File.expand_path(File.dirname(__FILE__)), "..", "VERSION")).freeze
|
29
|
+
|
30
|
+
#Class for errors in this library.
|
31
|
+
class XError < StandardError
|
32
|
+
end
|
33
|
+
|
34
|
+
class ParseError < StandardError
|
35
|
+
end
|
36
|
+
|
37
|
+
end #module XDo
|
@@ -0,0 +1,208 @@
|
|
1
|
+
#Encoding: UTF-8
|
2
|
+
#This file is part of Xdo.
|
3
|
+
#Copyright © 2009, 2010 Marvin Gülker
|
4
|
+
# Initia in potestate nostra sunt, de eventu fortuna iudicat.
|
5
|
+
|
6
|
+
require_relative("../xdo")
|
7
|
+
|
8
|
+
module XDo
|
9
|
+
|
10
|
+
#A module for interaction with the X clipboard. Please note, that the X clipboard
|
11
|
+
#consists of three parts: The PRIMARY clipboard, the CLIPBOARD clipboard, and
|
12
|
+
#the SECONDARY clipboard. The clipboard you access normally via [CTRL]+[C]
|
13
|
+
#or by right-clicking and selecting "copy", is usually the CLIPBOARD clipboard (but that
|
14
|
+
#depends on the application you use). The three main methods of this module (#read, #write
|
15
|
+
#and #clear) take a list symbols of the clipboards to interact with. If you don't want to
|
16
|
+
#pass in the symbols, use the predefined read_xy, write_xy and clear_xy methods. They cannot
|
17
|
+
#access more than one clipboard at a time.
|
18
|
+
#The symbols for the clipboards are:
|
19
|
+
#[PRIMARY] :primary
|
20
|
+
#[SECONDARY] :secondary
|
21
|
+
#[CLIPBOARD] :clipboard
|
22
|
+
#You cannot store complex objects like images via this interface, only strings. However,
|
23
|
+
#you could translate an image into a string (packed pixels maybe?) and put that on the
|
24
|
+
#clipboard -- for your own application this may be fine, but it won't magically allow
|
25
|
+
#a user to paste that image into a graphics program.
|
26
|
+
#
|
27
|
+
#The +xsel+ program used by this module is quite outdated. As far as I can see, it's
|
28
|
+
#last update happened in 2002 and since I do not believe that software exists that
|
29
|
+
#won't break over a period of 8 years without a single modification while updating systems I'm about to
|
30
|
+
#switch to a newer one. +xclip+ is likely, but that one got it's last update in early
|
31
|
+
#2009...
|
32
|
+
module Clipboard
|
33
|
+
|
34
|
+
class << self
|
35
|
+
|
36
|
+
##
|
37
|
+
# :singleton-method: read_primary
|
38
|
+
#Returns the contents of the PRIMARY clipboard.
|
39
|
+
#See #read for an explanation.
|
40
|
+
|
41
|
+
##
|
42
|
+
# :singleton-method: read_clipboard
|
43
|
+
#Returns the contents of the CLIPBOARD clipboard.
|
44
|
+
#See #read for an explanation.
|
45
|
+
|
46
|
+
##
|
47
|
+
# :singleton-method: read_secondary
|
48
|
+
#Returns the contents of the SECONDARY clipboard.
|
49
|
+
#See #read for an explanation.
|
50
|
+
|
51
|
+
##
|
52
|
+
# :singleton-method: write_primary
|
53
|
+
#Writes to the PRIMARY clipboard.
|
54
|
+
#See #write for an explanation.
|
55
|
+
|
56
|
+
##
|
57
|
+
# :singleton-method: write_clipboard
|
58
|
+
#Writes to the CLIPBOARD clipboard.
|
59
|
+
#See #write for an explanation.
|
60
|
+
|
61
|
+
##
|
62
|
+
# :singleton-method: write_secondary
|
63
|
+
#Writes to the SECONDARY clipboard.
|
64
|
+
#See #write for an explanation.
|
65
|
+
|
66
|
+
##
|
67
|
+
# :singleton-method: clear_primary
|
68
|
+
#Clears the PRIMARY clipboard.
|
69
|
+
#See #clear for an explanation.
|
70
|
+
|
71
|
+
##
|
72
|
+
# :singleton-method: clear_clipboard
|
73
|
+
#Clears the CLIPBOARD clipboard.
|
74
|
+
#See #clear for an explanation.
|
75
|
+
|
76
|
+
##
|
77
|
+
# :singleton-method: clear_secondary
|
78
|
+
#Clears the SECONDARY clipboard.
|
79
|
+
#See #clear for an explanation.
|
80
|
+
|
81
|
+
#Reads text from a X clipboard.
|
82
|
+
#===Parameters
|
83
|
+
#[<tt>*from</tt>] (<tt>:clipboard</tt>, <tt>:primary</tt>, <tt>:secondary</tt>) Specifies from which clipboards you want to read (in 70% of all cases you want to read from <tt>:clipboard</tt>).
|
84
|
+
#===Return value
|
85
|
+
#A hash of form
|
86
|
+
# {:clip_sym => "clipboard_content"}
|
87
|
+
#If you didn't pass any arguments to #read, the hash will contain keys for
|
88
|
+
#all clipboard, i.e. for <tt>:clipboard</tt>, <tt>:primary</tt> and <tt>:secondary</tt>.
|
89
|
+
#If you did, only those symbols will be included you passed. See
|
90
|
+
#the _Example_ section for an example of this.
|
91
|
+
#===Example
|
92
|
+
# XDo::Clipboard.read #| {:clipboard => "...", :primary => "...", :secondary => "..."}
|
93
|
+
# XDo::Clipboard.read(:primary) #| {:primary => "..."}
|
94
|
+
# XDo::Clipboard.read(:clipboard, :secondary) #| {clipboard => "...", :secondary => "..."}
|
95
|
+
#===Remarks
|
96
|
+
#You could also use one of the read_* methods for convenience.
|
97
|
+
def read(*from)
|
98
|
+
if from.first.kind_of? Hash
|
99
|
+
warn("#{caller.first}: Deprecation warning: Use symbols as a rest argument now!")
|
100
|
+
from = from.first.keys
|
101
|
+
end
|
102
|
+
from.concat([:clipboard, :primary, :secondary]) if from.empty?
|
103
|
+
|
104
|
+
hsh = {}
|
105
|
+
hsh[:primary] = `#{XSEL}` if from.include? :primary
|
106
|
+
hsh[:clipboard] = `#{XSEL} -b` if from.include? :clipboard
|
107
|
+
hsh[:secondary] = `#{XSEL} -s` if from.include? :secondary
|
108
|
+
hsh
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
#Writes text to a X clipboard.
|
113
|
+
#===Parameters
|
114
|
+
#[<tt>*to</tt>] (<tt>:clipboard</tt>) Specifies to what clipboards you want to wrote to.
|
115
|
+
#===Return value
|
116
|
+
#The text written.
|
117
|
+
#===Example
|
118
|
+
# XDo::Clipboard.write("I love Ruby") #You can now paste this via [CTRL] + [V]
|
119
|
+
# XDo::Clipboard.write("I love Ruby", :primary) #You can now paste this via a middle-mouse-button click
|
120
|
+
# XDo::Clipboard.write("I love Ruby", :clipboard, :primary) #Both of the above
|
121
|
+
#===Remarks
|
122
|
+
#You could also use one of the write_* methods for convenience.
|
123
|
+
def write(text, *to)
|
124
|
+
if to.first.kind_of? Hash
|
125
|
+
warn("#{caller.first}: Deprecation warning: Use symbols as a rest argument now!")
|
126
|
+
to = to.first.keys
|
127
|
+
end
|
128
|
+
to << :clipboard if to.empty?
|
129
|
+
|
130
|
+
IO.popen("xsel -i", "w"){|io| io.write(text)} if to.include? :primary
|
131
|
+
IO.popen("xsel -b -i", "w"){|io| io.write(text)} if to.include? :clipboard
|
132
|
+
IO.popen("xsel -s -i", "w"){|io| io.write(text)} if to.include? :secondary
|
133
|
+
text
|
134
|
+
end
|
135
|
+
|
136
|
+
#Appends text to a X clipboard.
|
137
|
+
#===Parameters
|
138
|
+
#[+text+] The text to append.
|
139
|
+
#[<tt>*to</tt>] (<tt>:clipboard</tt>) The clipboards to which you want to append.
|
140
|
+
#===Return value
|
141
|
+
#Undefined.
|
142
|
+
#===Example
|
143
|
+
# XDo::Clipboard.write("I love ")
|
144
|
+
# XDo::Clipboard.append("Ruby")
|
145
|
+
# puts XDo::Clipboard.read(:clipboard)[:clipboard] #=> I love Ruby
|
146
|
+
#
|
147
|
+
# XDo::Clipboard.write("I love", :primary)
|
148
|
+
# XDo::Clipboard.append("Ruby", :primary, :clipboard)
|
149
|
+
# #If you now paste via [CTRL] + [V], you'll get 'Ruby'. If you
|
150
|
+
# #paste via the middle mouse button, you'll get 'I love Ruby'
|
151
|
+
# #(Assuming you didn't execute the first block of code, of course).
|
152
|
+
def append(text, *to)
|
153
|
+
if to.first.kind_of? Hash
|
154
|
+
warn("#{caller.first}: Deprecation warning: Use symbols as a rest argument now!")
|
155
|
+
to = to.first.keys
|
156
|
+
end
|
157
|
+
to << :clipboard if to.empty?
|
158
|
+
|
159
|
+
IO.popen("xsel -a -i", "w"){|io| io.write(text)} if to.include? :primary
|
160
|
+
IO.popen("xsel -b -a -i", "w"){|io| io.write(text)} if to.include? :clipboard
|
161
|
+
IO.popen("xsel -s -a -i", "w"){|io| io.write(text)} if to.include? :secondary
|
162
|
+
end
|
163
|
+
|
164
|
+
#Clears the specified clipboards.
|
165
|
+
#===Parameters
|
166
|
+
#[<tt>*clips</tt>] (<tt>:primary</tt>, <tt>:clipboard</tt>, <tt>:secondary</tt>) The clipboards you want to clear.
|
167
|
+
#===Return value
|
168
|
+
#nil.
|
169
|
+
#===Example
|
170
|
+
# XDo::Clipboard.write("I love Ruby")
|
171
|
+
# XDo::Clipboard.clear
|
172
|
+
# #Nothing can be pasted anymore
|
173
|
+
#
|
174
|
+
# XDo::Clipboard.write("I love Ruby", :clipboard, :primary)
|
175
|
+
# XDo::Clipboard.clear(:primary)
|
176
|
+
# #You can still paste via [CTRL] + [V], but not with the middle mouse button
|
177
|
+
def clear(*clips)
|
178
|
+
if clips.first.kind_of? Hash
|
179
|
+
warn("#{caller.first}: Deprecation warning: Use symbols as a rest argument now!")
|
180
|
+
clips = clips.first.keys
|
181
|
+
end
|
182
|
+
clips.concat([:primary, :clipboard, :secondary]) if clips.empty?
|
183
|
+
|
184
|
+
`#{XSEL} -c` if clips.include? :primary
|
185
|
+
`#{XSEL} -b -c` if clips.include? :clipboard
|
186
|
+
`#{XSEL} -s -c` if clips.include? :secondary
|
187
|
+
nil
|
188
|
+
end
|
189
|
+
|
190
|
+
[:primary, :clipboard, :secondary].each do |sym|
|
191
|
+
|
192
|
+
define_method(:"read_#{sym}") do
|
193
|
+
read(sym)[sym]
|
194
|
+
end
|
195
|
+
|
196
|
+
define_method(:"write_#{sym}") do |text|
|
197
|
+
write(text, sym)
|
198
|
+
end
|
199
|
+
|
200
|
+
define_method(:"clear_#{sym}") do
|
201
|
+
clear(sym)
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|