xlib-objects 0.4.0 → 0.5.0

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.
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