uh 1.0.1 → 1.1.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: 1ef1227406e129065ec58d3ccbef8e530c74050f
4
- data.tar.gz: 3fb7f59ba3e5c3853a0e5c0f488b031b0ce5362f
3
+ metadata.gz: e23c0e6ca2adc65543ea88a899d518a66f6ba87d
4
+ data.tar.gz: ecda150aaa445463377e82efa6ff16c260fb4cab
5
5
  SHA512:
6
- metadata.gz: 5898495c89370be4a3e77478bf49fc944051677aae34e38d653afe7a7012a9fc2276298de8ee77052b89566d1759724c16c4082582128d6be34ba305f53fd72c
7
- data.tar.gz: 942d61b82d905b2bef029bd551db2709770b58a9ef4a308068d186a2e3b1aedadcf1bdecf3767be911c97bd7c83ba210734ac91313c18b4425b9d0d654fb84a8
6
+ metadata.gz: 38c121dd15a0616f48b32aec6f2961e2e2393d7a4216e1d9ae712a0cd354b77e48ff602a631746e1b44695669cb113e57dc8f2c580b47a3ce593a656ac97fee4
7
+ data.tar.gz: 0363cabe4cab460b7a94d29ec85f2c04fb93a523f6e615771f5d360438bfc6058dc2a92b13abd3c5175e6a8ff04ee00072fe3227aed8a4fe99270f6980d11d98
@@ -87,6 +87,8 @@ VALUE event_make_event(VALUE klass, XEvent *xev) {
87
87
  event = Data_Wrap_Struct(klass, 0, 0, xev);
88
88
  rb_ivar_set(event, rb_intern("@type"),
89
89
  ID2SYM(rb_intern(type_descs[xev->type])));
90
+ rb_ivar_set(event, rb_intern("@send_event"),
91
+ xev->xany.send_event ? Qtrue : Qfalse);
90
92
 
91
93
  return event;
92
94
  }
@@ -152,6 +154,8 @@ void event_make_win_any(VALUE self) {
152
154
  window = xev->xproperty.window;
153
155
  break;
154
156
  case UnmapNotify:
157
+ rb_ivar_set(self, rb_intern("@event_window"),
158
+ window_make(xev->xany.display, xev->xunmap.event));
155
159
  window = xev->xunmap.window;
156
160
  break;
157
161
  default:
data/lib/uh.rb CHANGED
@@ -2,6 +2,7 @@ require 'uh/uh'
2
2
  require 'uh/display'
3
3
  require 'uh/drawable'
4
4
  require 'uh/events'
5
+ require 'uh/events/event'
5
6
  require 'uh/font'
6
7
  require 'uh/geo'
7
8
  require 'uh/pixmap'
@@ -0,0 +1,7 @@
1
+ module Uh
2
+ module Events
3
+ class Event
4
+ attr_reader :send_event, :event_window
5
+ end
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  module Uh
2
- VERSION = '1.0.1'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
@@ -51,7 +51,7 @@ module Uh
51
51
  o.level = ENV.key?(LOGGER_DEBUG_ENV) ? Logger::DEBUG : LOGGER_LEVEL
52
52
  o.formatter = LOGGER_FORMATER
53
53
  end
54
- @manager = Manager.new(@logger)
54
+ @manager = Manager.new
55
55
  @actions = ActionHandler.new(self, @manager, @layout)
56
56
  @keys = {}
57
57
  @rules = {}
@@ -148,10 +148,8 @@ module Uh
148
148
  end
149
149
 
150
150
  def log_event(event)
151
- fmt = '> Event %s'
152
- complement = case event.type
153
- when :destroy_notify, :expose, :key_press, :map_request, :property_notify,
154
- :unmap_notify
151
+ complement = case event.type
152
+ when :destroy_notify, :expose, :key_press, :map_request, :property_notify
155
153
  "window: #{event.window}"
156
154
  when :configure_request
157
155
  '%s, above: #%d, detail: #%d, value_mask: #%d' % [
@@ -160,11 +158,15 @@ module Uh
160
158
  event.detail,
161
159
  event.value_mask
162
160
  ]
163
- else
164
- nil
161
+ when :unmap_notify
162
+ "window: #{event.window}, event_window: #{event.event_window}"
165
163
  end
166
164
 
167
- log 'XEvent %s' % [event.type, complement].compact.join(' ')
165
+ log [
166
+ 'XEvent', event.type,
167
+ event.send_event ? 'SENT' : nil,
168
+ complement
169
+ ].compact.join(' ')
168
170
  end
169
171
 
170
172
  def handle_configure_request(event)
@@ -6,23 +6,25 @@ module Uh
6
6
  include GeoAccessors
7
7
 
8
8
  attr_reader :window
9
- attr_accessor :geo
9
+ attr_accessor :geo, :unmap_count
10
10
 
11
11
  def initialize(window)
12
- @window = window
13
- @hide = true
12
+ @window = window
13
+ @hide = true
14
+ @unmap_count = 0
14
15
  end
15
16
 
16
17
  def to_s
17
- '<%s> (%s) window: %s, geo: %s' % [name, wclass, window, geo]
18
+ '<%s> (%s) %s win: %s unmaps: %d' %
19
+ [name, wclass, @geo, @window, @unmap_count]
18
20
  end
19
21
 
20
22
  def name
21
- @name ||= window.name
23
+ @name ||= @window.name
22
24
  end
23
25
 
24
26
  def wclass
25
- @wclass ||= window.wclass
27
+ @wclass ||= @window.wclass
26
28
  end
27
29
 
28
30
  def hidden?
@@ -35,44 +37,45 @@ module Uh
35
37
  end
36
38
 
37
39
  def configure
38
- window.configure geo
40
+ @window.configure @geo
39
41
  self
40
42
  end
41
43
 
42
44
  def moveresize
43
- window.moveresize geo
45
+ @window.moveresize @geo
44
46
  self
45
47
  end
46
48
 
47
49
  def show
48
- window.map
50
+ @window.map
49
51
  @hide = false
50
52
  self
51
53
  end
52
54
 
53
55
  def hide
54
- window.unmap
56
+ @window.unmap
55
57
  @hide = true
58
+ @unmap_count += 1
56
59
  self
57
60
  end
58
61
 
59
62
  def focus
60
- window.raise
61
- window.focus
63
+ @window.raise
64
+ @window.focus
62
65
  self
63
66
  end
64
67
 
65
68
  def kill
66
- if window.icccm_wm_protocols.include? :WM_DELETE_WINDOW
67
- window.icccm_wm_delete
69
+ if @window.icccm_wm_protocols.include? :WM_DELETE_WINDOW
70
+ @window.icccm_wm_delete
68
71
  else
69
- window.kill
72
+ @window.kill
70
73
  end
71
74
  self
72
75
  end
73
76
 
74
77
  def kill!
75
- window.kill
78
+ @window.kill
76
79
  self
77
80
  end
78
81
  end
@@ -3,12 +3,10 @@ module Uh
3
3
  class Manager
4
4
  DEFAULT_GEO = Geo.new(0, 0, 320, 240).freeze
5
5
 
6
- extend Forwardable
7
- def_delegator :@logger, :info, :log
6
+ attr_reader :clients
8
7
 
9
- def initialize(logger)
10
- @logger = logger
11
- @clients = []
8
+ def initialize
9
+ @clients = []
12
10
  end
13
11
 
14
12
  def to_s
@@ -33,35 +31,30 @@ module Uh
33
31
 
34
32
  def configure(window)
35
33
  if client = client_for(window)
36
- log "#{self.class.name}#configure #{client} already managed"
37
34
  client.configure
38
35
  else
39
36
  geo = @on_configure ? @on_configure.call(window) : DEFAULT_GEO
40
- log "#{self.class.name}#configure window: #{window}, not managed"
41
- log "#{window.class.name}#configure #{geo}"
42
37
  window.configure_event geo
43
38
  end
44
39
  end
45
40
 
46
41
  def map(window)
47
- if window.override_redirect?
48
- log "#{self.class.name}#map #{window}.override_redirect, skipping"
49
- return
50
- end
51
-
52
- if client = client_for(window)
53
- log "#{self.class.name}#map #{client}, already managed"
54
- nil
55
- else
56
- Client.new(window).tap { |o| manage o }
57
- end
42
+ return if window.override_redirect? || client_for(window)
43
+ Client.new(window).tap { |o| manage o }
58
44
  end
59
45
 
60
46
  def unmap(window)
47
+ return unless client = client_for(window)
48
+ if client.unmap_count > 0
49
+ client.unmap_count -= 1
50
+ else
51
+ unmanage client
52
+ end
61
53
  end
62
54
 
63
55
  def destroy(window)
64
- remove_client_for window
56
+ return unless client = client_for(window)
57
+ unmanage client
65
58
  end
66
59
 
67
60
  def update_properties(window)
@@ -77,19 +70,12 @@ module Uh
77
70
  @clients.find { |e| e.window == window }
78
71
  end
79
72
 
80
- def remove_client_for(window)
81
- return unless client = client_for(window)
82
- unmanage client
83
- end
84
-
85
73
  def manage(client)
86
- log "#{self.class.name}#manage #{client}"
87
74
  @clients << client
88
75
  @on_manage.call client if @on_manage
89
76
  end
90
77
 
91
78
  def unmanage(client)
92
- log "#{self.class.name}#unmanage #{client}"
93
79
  @clients.reject! { |e| e == client }
94
80
  @on_unmanage.call client if @on_unmanage
95
81
  end
@@ -15,6 +15,10 @@ module Uh
15
15
  assert subject.hidden?
16
16
  end
17
17
 
18
+ it 'has an unmap count of 0' do
19
+ assert_equal 0, subject.unmap_count
20
+ end
21
+
18
22
  describe '#name' do
19
23
  it 'returns the window name' do
20
24
  assert_equal 'win name', subject.name
@@ -98,11 +102,16 @@ module Uh
98
102
  window.verify
99
103
  end
100
104
 
101
- it 'is stays hidden' do
105
+ it 'stays hidden' do
102
106
  subject.hide
103
107
  assert subject.hidden?
104
108
  end
105
109
 
110
+ it 'increments the unmap count' do
111
+ subject.hide
112
+ assert_equal 1, subject.unmap_count
113
+ end
114
+
106
115
  it 'returns self' do
107
116
  assert_same subject, subject.hide
108
117
  end
@@ -0,0 +1,164 @@
1
+ require 'test_helper'
2
+ require 'uh/wm'
3
+
4
+ module Uh
5
+ class WM
6
+ describe Manager do
7
+ let(:output) { StringIO.new }
8
+ let(:window) { Minitest::Mock.new }
9
+ subject { Manager.new }
10
+
11
+ it 'has no clients' do
12
+ assert subject.clients.empty?
13
+ end
14
+
15
+ describe '#configure' do
16
+ context 'with new window' do
17
+ it 'sends a default configure event to the window' do
18
+ window.expect :configure_event, window, [Geo.new(0, 0, 320, 240)]
19
+ subject.configure window
20
+ window.verify
21
+ end
22
+
23
+ context 'with a registered callback' do
24
+ it 'sends configure event with geo returned by callback' do
25
+ subject.on_configure { Geo.new(0, 0, 42, 42) }
26
+ window.expect :configure_event, window, [Geo.new(0, 0, 42, 42)]
27
+ subject.configure window
28
+ window.verify
29
+ end
30
+ end
31
+ end
32
+
33
+ context 'with known window' do
34
+ let(:client) { Minitest::Mock.new }
35
+
36
+ before do
37
+ subject.clients << client
38
+ client.expect :window, window
39
+ end
40
+
41
+ it 'sends a configure message to the client for given window' do
42
+ window.expect :==, true, [Object]
43
+ client.expect :configure, client
44
+ subject.configure window
45
+ client.verify
46
+ end
47
+ end
48
+ end
49
+
50
+ describe '#map' do
51
+ before do
52
+ window.expect :override_redirect?, false
53
+ end
54
+
55
+ it 'registers a new client' do
56
+ subject.map window
57
+ assert_equal 1, subject.clients.size
58
+ end
59
+
60
+ it 'calls the manage callback' do
61
+ subject.on_manage do |client|
62
+ assert_equal subject.clients[0], client
63
+ throw :manage
64
+ end
65
+ assert_throws(:manage) { subject.map window }
66
+ end
67
+ end
68
+
69
+ describe '#unmap' do
70
+ let(:client) { Client.new(window) }
71
+
72
+ before do
73
+ subject.clients << client
74
+ window.expect :==, true, [Object]
75
+ end
76
+
77
+ context 'when client unmap count is 0 or less' do
78
+ it 'preserves the unmap count' do
79
+ subject.unmap window
80
+ assert_equal 0, client.unmap_count
81
+ end
82
+
83
+ it 'unmanages the client' do
84
+ subject.unmap window
85
+ refute_includes subject.clients, client
86
+ end
87
+
88
+ it 'calls the unmanage callback' do
89
+ subject.on_unmanage do |c|
90
+ assert_equal client, c
91
+ throw :unmanage
92
+ end
93
+ assert_throws(:unmanage) { subject.unmap window }
94
+ end
95
+ end
96
+
97
+ context 'when client unmap count is strictly positive' do
98
+ before { client.unmap_count += 1 }
99
+
100
+ it 'decrements the unmap count' do
101
+ subject.unmap window
102
+ assert_equal 0, client.unmap_count
103
+ end
104
+
105
+ it 'does not unmanage the client' do
106
+ subject.unmap window
107
+ assert_includes subject.clients, client
108
+ end
109
+ end
110
+ end
111
+
112
+ describe '#destroy' do
113
+ let(:client) { Client.new(window) }
114
+
115
+ before do
116
+ subject.clients << client
117
+ window.expect :==, true, [Object]
118
+ end
119
+
120
+ it 'unmanages the client' do
121
+ subject.destroy window
122
+ refute_includes subject.clients, client
123
+ end
124
+
125
+ it 'calls the unmanage callback' do
126
+ subject.on_unmanage do |c|
127
+ assert_equal client, c
128
+ throw :unmanage
129
+ end
130
+ assert_throws(:unmanage) { subject.destroy window }
131
+ end
132
+ end
133
+
134
+ describe '#update_properties' do
135
+ context 'with known window' do
136
+ before do
137
+ window.expect :==, true, [Object]
138
+ window.expect :name, 'window'
139
+ window.expect :wclass, 'window class'
140
+ end
141
+
142
+ it 'updates client window properties' do
143
+ client = Minitest::Mock.new
144
+ client.expect :window, window
145
+ subject.clients << client
146
+ client.expect :update_window_properties, client
147
+ subject.update_properties window
148
+ client.verify
149
+ end
150
+
151
+ it 'calls the change callback' do
152
+ client = Client.new(window)
153
+ subject.clients << client
154
+ subject.on_change do |c|
155
+ assert_same client, c
156
+ throw :change
157
+ end
158
+ assert_throws(:change) { subject.update_properties window }
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uh
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thibault Jouan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-15 00:00:00.000000000 Z
11
+ date: 2015-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -92,6 +92,7 @@ files:
92
92
  - lib/uh/display.rb
93
93
  - lib/uh/drawable.rb
94
94
  - lib/uh/events.rb
95
+ - lib/uh/events/event.rb
95
96
  - lib/uh/font.rb
96
97
  - lib/uh/geo.rb
97
98
  - lib/uh/geo_accessors.rb
@@ -110,6 +111,7 @@ files:
110
111
  - test/uh/test_geo.rb
111
112
  - test/uh/test_wm.rb
112
113
  - test/uh/wm/test_client.rb
114
+ - test/uh/wm/test_manager.rb
113
115
  - uh.gemspec
114
116
  homepage: https://rubygems.org/gems/uh
115
117
  licenses: []
@@ -139,4 +141,5 @@ test_files:
139
141
  - test/uh/test_geo.rb
140
142
  - test/uh/test_wm.rb
141
143
  - test/uh/wm/test_client.rb
144
+ - test/uh/wm/test_manager.rb
142
145
  has_rdoc: