xlib-objects 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4658e68ce4cbae5cf14d45379d8866754d0b230a
4
- data.tar.gz: 933215482798422789ccaf799af996960d2e8eed
3
+ metadata.gz: 88f009cd9b2bead97318e62d2dc2eb5398156d2e
4
+ data.tar.gz: 038d2d50a883a97dfda1442a046b86f420905e20
5
5
  SHA512:
6
- metadata.gz: a303e9c96e74040b2d2a6a2731adcece55911d818046d093d22de2af2dfe7fc09bb10c09d769d0935971526e241b59185d6481ca8e125db3d46285db5b7a62cb
7
- data.tar.gz: f6d1fadb43dc41a79f7a19b55c422e64d90fc935ae16316261d09c4eb2f28239ed0bc1ca8f8941f0a2175827cfdb6d00365bb7c7b7a8cda91440619b1a6f69b0
6
+ metadata.gz: 1ef8e3f5832173185ec963d433a90ad7e64b3669caba19517a93e58ecca8390a07af1344e4d545e207eb4be6603b94906f0bd184624d03b7fb9721369d064e51
7
+ data.tar.gz: 8f5b9e742bff08d20c45e989938886a5f8c1a3a756da3ec3f131429e0b2cf9735f880c43e2ea540cd2095d895c2e59abdabd87ff642290a06ee59539897614c4
data/lib/display.rb CHANGED
@@ -49,9 +49,13 @@ module XlibObj
49
49
  handle_event(next_event) while pending_events > 0
50
50
  end
51
51
 
52
- def clipboard(type = :CLIPBOARD, &on_receive)
53
- @internal_window ||= screen.root_window.create_window
54
- @internal_window.request_selection(type: type, &on_receive)
52
+ def selection(*args, &on_receive)
53
+ internal_window.request_selection(*args, &on_receive)
54
+ self
55
+ end
56
+
57
+ def set_selection(*args, &on_request)
58
+ internal_window.set_selection(*args, &on_request)
55
59
  self
56
60
  end
57
61
 
@@ -84,6 +88,10 @@ module XlibObj
84
88
 
85
89
  private
86
90
 
91
+ def internal_window
92
+ @internal_window ||= screen.root_window.create_window
93
+ end
94
+
87
95
  def pending_events
88
96
  Xlib.XPending(to_native)
89
97
  end
@@ -95,7 +103,7 @@ module XlibObj
95
103
  end
96
104
 
97
105
  def handle_event(event)
98
- handling_window_id = event.event || event.parent || event.window || event.requestor
106
+ handling_window_id = event.event || event.parent || event.window || event.owner || event.requestor
99
107
  handling_window = Window.new(self, handling_window_id)
100
108
  handling_window.handle(event)
101
109
  end
@@ -0,0 +1,35 @@
1
+ #
2
+ # Copyright (c) 2015 Christopher Aue <mail@christopheraue.net>
3
+ #
4
+ # This file is part of the ruby xlib-objects gem. It is subject to the license
5
+ # terms in the LICENSE file found in the top-level directory of this
6
+ # distribution and at http://github.com/christopheraue/ruby-xlib-objects.
7
+ #
8
+
9
+ module XlibObj
10
+ class Event
11
+ class SelectionNotify
12
+ def initialize(type:, target:, property:)
13
+ @type, @target, @property = type, target, property
14
+ end
15
+
16
+ def send_to(receiver)
17
+ Xlib.XSendEvent(receiver.display.to_native, receiver.to_native, false, 0, event(receiver))
18
+ Xlib.XFlush(receiver.display.to_native)
19
+ end
20
+
21
+ private
22
+
23
+ def event(receiver)
24
+ event = Xlib::XEvent.new
25
+ event[:xselection][:type] = Xlib::SelectionNotify
26
+ event[:xselection][:requestor] = receiver.to_native
27
+ event[:xselection][:selection] = Atom.new(receiver.display, @type).to_native
28
+ event[:xselection][:target] = Atom.new(receiver.display, @target).to_native
29
+ event[:xselection][:property] = Atom.new(receiver.display, @property).to_native
30
+ event[:xselection][:time] = Xlib::CurrentTime
31
+ event.pointer
32
+ end
33
+ end
34
+ end
35
+ end
@@ -34,7 +34,7 @@ module XlibObj
34
34
  add_event_handler(mask, event, &handler)
35
35
  end
36
36
 
37
- def off(mask, type, handler)
37
+ def off(mask, type, handler = nil)
38
38
  remove_event_handler(mask, type, handler)
39
39
  remove_event_mask(mask)
40
40
  end
@@ -84,8 +84,8 @@ module XlibObj
84
84
  check_event(event)
85
85
  return unless mask_in_use?(mask)
86
86
  return unless @event_handlers[event]
87
- @event_handlers[event][mask].delete(handler)
88
- @event_handlers[event].delete(mask) if @event_handlers[event][mask].empty?
87
+ @event_handlers[event][mask].delete(handler) if handler
88
+ @event_handlers[event].delete(mask) if @event_handlers[event][mask].empty? or handler.nil?
89
89
  @event_handlers.delete(event) if @event_handlers[event].empty?
90
90
  end
91
91
 
data/lib/window.rb CHANGED
@@ -38,14 +38,6 @@ module XlibObj
38
38
  Property.new(self, name).get
39
39
  end
40
40
 
41
- def set_property(name, value)
42
- Property.new(self, name).set(value)
43
- end
44
-
45
- def delete_property(name)
46
- Property.new(self, name).delete
47
- end
48
-
49
41
  def absolute_position
50
42
  x_abs = FFI::MemoryPointer.new :int
51
43
  y_abs = FFI::MemoryPointer.new :int
@@ -58,7 +50,22 @@ module XlibObj
58
50
  { x: x_abs.read_int, y: y_abs.read_int }
59
51
  end
60
52
 
53
+ def focused?
54
+ focused_window = FFI::MemoryPointer.new :Window
55
+ focus_state = FFI::MemoryPointer.new :int
56
+ Xlib.XGetInputFocus(@display.to_native, focused_window, focus_state)
57
+ focused_window.read_int == @to_native
58
+ end
59
+
61
60
  # Commands
61
+ def set_property(name, value)
62
+ Property.new(self, name).set(value)
63
+ end
64
+
65
+ def delete_property(name)
66
+ Property.new(self, name).delete
67
+ end
68
+
62
69
  def move_resize(x, y, width, height)
63
70
  Xlib.XMoveResizeWindow(@display.to_native, @to_native, x, y, width, height)
64
71
  Xlib.XFlush(@display.to_native)
@@ -99,7 +106,13 @@ module XlibObj
99
106
  @event_handler.on(mask, type, &callback)
100
107
  end
101
108
 
102
- def off(mask, type, callback)
109
+ def until_true(mask, type, &callback)
110
+ handler = on(mask, type) do |*args|
111
+ off(mask, type, handler) if callback.call(*args)
112
+ end
113
+ end
114
+
115
+ def off(mask, type, callback = nil)
103
116
  @event_handler.off(mask, type, callback)
104
117
  self
105
118
  end
@@ -114,30 +127,76 @@ module XlibObj
114
127
  self
115
128
  end
116
129
 
117
- def request_selection(type: :PRIMARY, format: :UTF8_STRING, property: :XSEL_DATA, &on_receive)
130
+ def request_selection(type = :PRIMARY, target: :UTF8_STRING, property: :XSEL_DATA, &on_receive)
118
131
  # will only receive the selection notify event, if the window has been created by the process
119
132
  # running this very code
120
- selection_handler = on(:no_event, :selection_notify) do |event|
121
- next if Atom.new(@display, event.selection).name != type
122
- next if Atom.new(@display, event.target).name != format
133
+ until_true(:no_event, :selection_notify) do |event|
134
+ break false if Atom.new(@display, event.selection).name != type
135
+ break false if Atom.new(@display, event.target).name != target
123
136
 
137
+ # query selection content
124
138
  if event.property == Xlib::None
125
139
  selection = nil
126
140
  else
127
141
  selection = property(event.property)
128
142
  delete_property(event.property)
129
143
  end
130
- selection_owner = Window.new(@display, Xlib.XGetSelectionOwner(@display, event.selection))
144
+
145
+ # send selection to callback
146
+ selection_owner = Window.new(@display, Xlib.XGetSelectionOwner(@display.to_native, event.selection))
131
147
  on_receive.call(selection, type, selection_owner)
132
- off(:no_event, :selection_notify, selection_handler)
148
+
149
+ true
133
150
  end
134
151
 
152
+ # request the selection
135
153
  type_atom = Atom.new(@display, type)
154
+ target_atom = Atom.new(@display, target)
136
155
  property_atom = Atom.new(@display, property)
137
- format_atom = Atom.new(@display, format)
138
- Xlib.XConvertSelection(@display.to_native, type_atom.to_native, format_atom.to_native,
156
+ Xlib.XConvertSelection(@display.to_native, type_atom.to_native, target_atom.to_native,
139
157
  property_atom.to_native, @to_native, Xlib::CurrentTime)
140
158
  Xlib.XFlush(@display.to_native)
159
+
160
+ self
161
+ end
162
+
163
+ def set_selection(type = :PRIMARY, targets: [:UTF8_STRING, :STRING, :TEXT], &on_request)
164
+ type_atom = Atom.new(@display, type)
165
+ Xlib.XSetSelectionOwner(@display.to_native, type_atom.to_native, to_native, Xlib::CurrentTime)
166
+
167
+ request_handler = on(:no_event, :selection_request) do |event|
168
+ break if Atom.new(@display, event.selection).name != type
169
+
170
+ # convert selection
171
+ target = Atom.new(@display, event.target).name
172
+ selection = if target == :TARGETS
173
+ (targets + [:TARGETS]).map{ |t| Atom.new(@display, t) }
174
+ elsif targets.include? target
175
+ on_request.call(target)
176
+ end
177
+
178
+ # set property on requestor
179
+ requestor = Window.new(@display, event.requestor)
180
+ if selection
181
+ property = event.property == Xlib::None ? event.target : event.property
182
+ requestor.set_property(property, selection)
183
+
184
+ # notify requestor of set property
185
+ Event::SelectionNotify.new(type: event.selection, target: event.target, property: property).
186
+ send_to(requestor)
187
+ else
188
+ # notify requestor of failed conversion
189
+ Event::SelectionNotify.new(type: event.selection, target: event.target, property: Xlib::None).
190
+ send_to(requestor)
191
+ end
192
+ end
193
+
194
+ until_true(:no_event, :selection_clear) do |event|
195
+ break false if Atom.new(@display, event.selection).name != type
196
+ off(:no_event, :selection_request, request_handler)
197
+ true
198
+ end
199
+
141
200
  self
142
201
  end
143
202
 
data/lib/xlib-objects.rb CHANGED
@@ -15,6 +15,7 @@ require_relative 'display'
15
15
  require_relative 'event'
16
16
  require_relative 'error'
17
17
  require_relative 'event/client_message'
18
+ require_relative 'event/selection_notify'
18
19
  require_relative 'screen'
19
20
  require_relative 'screen/crtc'
20
21
  require_relative 'screen/crtc/output'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xlib-objects
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Aue
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-16 00:00:00.000000000 Z
11
+ date: 2015-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xlib
@@ -77,6 +77,7 @@ files:
77
77
  - lib/error.rb
78
78
  - lib/event.rb
79
79
  - lib/event/client_message.rb
80
+ - lib/event/selection_notify.rb
80
81
  - lib/screen.rb
81
82
  - lib/screen/crtc.rb
82
83
  - lib/screen/crtc/output.rb