xdo 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|