uh 1.0.1 → 1.1.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: 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: