uh 0.1.1
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 +7 -0
- data/.gitignore +4 -0
- data/Gemfile +5 -0
- data/Guardfile +7 -0
- data/Rakefile +11 -0
- data/TODO +17 -0
- data/ext/uh/color.c +12 -0
- data/ext/uh/display.c +234 -0
- data/ext/uh/event.c +161 -0
- data/ext/uh/extconf.rb +13 -0
- data/ext/uh/font.c +14 -0
- data/ext/uh/pixmap.c +92 -0
- data/ext/uh/screen.c +12 -0
- data/ext/uh/uh.c +139 -0
- data/ext/uh/uh.h +106 -0
- data/ext/uh/window.c +222 -0
- data/lib/uh.rb +28 -0
- data/lib/uh/display.rb +15 -0
- data/lib/uh/drawable.rb +7 -0
- data/lib/uh/events.rb +32 -0
- data/lib/uh/font.rb +7 -0
- data/lib/uh/geo.rb +42 -0
- data/lib/uh/pixmap.rb +5 -0
- data/lib/uh/screen.rb +7 -0
- data/lib/uh/version.rb +3 -0
- data/lib/uh/window.rb +35 -0
- data/lib/uh/wm.rb +199 -0
- data/lib/uh/wm/action_handler.rb +59 -0
- data/lib/uh/wm/client.rb +76 -0
- data/lib/uh/wm/manager.rb +99 -0
- data/lib/uh/wm/workers/base_worker.rb +20 -0
- data/lib/uh/wm/workers/blocking_worker.rb +11 -0
- data/lib/uh/wm/workers/multiplexing_worker.rb +27 -0
- data/test/test_helper.rb +13 -0
- data/test/uh/test_geo.rb +48 -0
- data/uh.gemspec +21 -0
- metadata +136 -0
data/lib/uh/wm/client.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
module Uh
|
2
|
+
class WM
|
3
|
+
class Client
|
4
|
+
attr_reader :window
|
5
|
+
attr_accessor :geo
|
6
|
+
|
7
|
+
def initialize(window)
|
8
|
+
@window = window
|
9
|
+
@hide = true
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
'<%s> (%s) window: %s, geo: %s' % [name, wclass, window, geo]
|
14
|
+
end
|
15
|
+
|
16
|
+
def name
|
17
|
+
@name ||= window.name
|
18
|
+
end
|
19
|
+
|
20
|
+
def wclass
|
21
|
+
@wclass ||= window.wclass
|
22
|
+
end
|
23
|
+
|
24
|
+
def hidden?
|
25
|
+
@hide
|
26
|
+
end
|
27
|
+
|
28
|
+
def update_window_properties
|
29
|
+
@name = @window.name
|
30
|
+
@wclass = @window.wclass
|
31
|
+
end
|
32
|
+
|
33
|
+
def configure
|
34
|
+
window.configure geo
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def moveresize
|
39
|
+
window.moveresize geo
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def show
|
44
|
+
window.map
|
45
|
+
@hide = false
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
def hide
|
50
|
+
window.unmap
|
51
|
+
@hide = true
|
52
|
+
self
|
53
|
+
end
|
54
|
+
|
55
|
+
def focus
|
56
|
+
window.raise
|
57
|
+
window.focus
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def kill
|
62
|
+
if window.icccm_wm_protocols.include? :WM_DELETE_WINDOW
|
63
|
+
window.icccm_wm_delete
|
64
|
+
else
|
65
|
+
window.kill!
|
66
|
+
end
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
def kill!
|
71
|
+
window.kill
|
72
|
+
self
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Uh
|
2
|
+
class WM
|
3
|
+
class Manager
|
4
|
+
DEFAULT_GEO = Geo.new(0, 0, 320, 240).freeze
|
5
|
+
|
6
|
+
extend Forwardable
|
7
|
+
def_delegator :@logger, :info, :log
|
8
|
+
|
9
|
+
def initialize(logger)
|
10
|
+
@logger = logger
|
11
|
+
@clients = []
|
12
|
+
@on_manage = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
@clients.join $/
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_configure(&block)
|
20
|
+
@on_configure = block
|
21
|
+
end
|
22
|
+
|
23
|
+
def on_manage(&block)
|
24
|
+
@on_manage << block
|
25
|
+
end
|
26
|
+
|
27
|
+
def on_unmanage(&block)
|
28
|
+
@on_unmanage = block
|
29
|
+
end
|
30
|
+
|
31
|
+
def on_change(&block)
|
32
|
+
@on_change = block
|
33
|
+
end
|
34
|
+
|
35
|
+
def configure(window)
|
36
|
+
if client = client_for(window)
|
37
|
+
log "#{self.class.name}#configure #{client} already managed"
|
38
|
+
client.configure
|
39
|
+
else
|
40
|
+
geo = @on_configure ? @on_configure.call(window) : DEFAULT_GEO
|
41
|
+
log "#{self.class.name}#configure window: #{window}, not managed"
|
42
|
+
log "#{window.class.name}#configure #{geo}"
|
43
|
+
window.configure_event geo
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def map(window)
|
48
|
+
if window.override_redirect?
|
49
|
+
log "#{self.class.name}#map window.override_redirect, skipping"
|
50
|
+
return
|
51
|
+
end
|
52
|
+
|
53
|
+
if client = client_for(window)
|
54
|
+
log "#{self.class.name}#map #{client}, already managed"
|
55
|
+
else
|
56
|
+
manage Client.new(window)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def unmap(window)
|
61
|
+
remove_client_for window
|
62
|
+
end
|
63
|
+
|
64
|
+
def destroy(window)
|
65
|
+
remove_client_for window, destroy: true
|
66
|
+
end
|
67
|
+
|
68
|
+
def update_properties(window)
|
69
|
+
return unless client = client_for(window)
|
70
|
+
client.update_window_properties
|
71
|
+
@on_change.call client if @on_change
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def client_for(window)
|
78
|
+
@clients.find { |e| e.window == window }
|
79
|
+
end
|
80
|
+
|
81
|
+
def remove_client_for(window, destroy: false)
|
82
|
+
return unless client = client_for(window)
|
83
|
+
unmanage client unless client.hidden? && !destroy
|
84
|
+
end
|
85
|
+
|
86
|
+
def manage(client)
|
87
|
+
log "#{self.class.name}#manage #{client}"
|
88
|
+
@clients << client
|
89
|
+
@on_manage.each { |e| e.call client }
|
90
|
+
end
|
91
|
+
|
92
|
+
def unmanage(client)
|
93
|
+
log "#{self.class.name}#unmanage #{client}"
|
94
|
+
@clients.reject! { |e| e == client }
|
95
|
+
@on_unmanage.call client if @on_unmanage
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Uh
|
2
|
+
class WM
|
3
|
+
module Workers
|
4
|
+
class BaseWorker
|
5
|
+
def initialize(display, logger, **options)
|
6
|
+
@display = display
|
7
|
+
@logger = logger
|
8
|
+
configure **options
|
9
|
+
end
|
10
|
+
|
11
|
+
def configure(**options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def setup
|
15
|
+
self
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Uh
|
2
|
+
class WM
|
3
|
+
module Workers
|
4
|
+
class MultiplexingWorker < BaseWorker
|
5
|
+
def configure(timeout: 4)
|
6
|
+
@timeout = timeout
|
7
|
+
end
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@display_io = IO.new(@display.fileno)
|
11
|
+
@display.flush
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def each_event
|
16
|
+
loop do
|
17
|
+
@logger.debug "select [#{@display_io.fileno}], _, _, #{@timeout}"
|
18
|
+
rs, _ = IO.select [@display_io], [], [], @timeout
|
19
|
+
@logger.debug " => #{rs.inspect}"
|
20
|
+
next if rs.nil? || rs.empty?
|
21
|
+
yield @display.next_event while @display.pending?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#require 'minitest/parallel'
|
2
|
+
require 'minitest/spec'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'minitest/reporters'
|
5
|
+
require 'uh'
|
6
|
+
|
7
|
+
class Minitest::Test
|
8
|
+
# FIXME: SpecReporter output is incorrect with pretty diffs or parallel tests
|
9
|
+
#make_my_diffs_pretty!
|
10
|
+
#parallelize_me!
|
11
|
+
end
|
12
|
+
|
13
|
+
Minitest::Reporters.use!(Minitest::Reporters::SpecReporter.new)
|
data/test/uh/test_geo.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Uh::Geo do
|
4
|
+
subject { Uh::Geo.new(0, 0, 640, 480) }
|
5
|
+
|
6
|
+
describe '.new' do
|
7
|
+
it 'raises error when invalid width is given' do
|
8
|
+
assert_raises(Uh::ArgumentError) { Uh::Geo.new(0, 0, 0, 480) }
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'raises error when invalid height is given' do
|
12
|
+
assert_raises(Uh::ArgumentError) { Uh::Geo.new(0, 0, 640, 0) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '.format_xgeometry' do
|
17
|
+
it 'formats coordinates and dimensions as X geometry' do
|
18
|
+
assert_equal '640x480+0+0', Uh::Geo.format_xgeometry(0, 0, 640, 480)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'formats missing values as ?' do
|
22
|
+
assert_equal '?x?+?+?', Uh::Geo.format_xgeometry(*[nil] * 4)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#to_s' do
|
27
|
+
it 'returns .format_xgeometry results' do
|
28
|
+
assert_equal Uh::Geo.format_xgeometry(*subject.values), subject.to_s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
%w[width height].each do |dimension|
|
33
|
+
describe "##{dimension}=" do
|
34
|
+
it 'assigns given value' do
|
35
|
+
subject.send "#{dimension}=", 42
|
36
|
+
assert_equal 42, subject.send(dimension)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'raises error when 0 is given' do
|
40
|
+
assert_raises(Uh::ArgumentError) { subject.send "#{dimension}=", 0 }
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'raises error when negative value is given' do
|
44
|
+
assert_raises(Uh::ArgumentError) { subject.send "#{dimension}=", -42 }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/uh.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path('../lib/uh/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'uh'
|
5
|
+
s.version = Uh::VERSION.dup
|
6
|
+
s.summary = 'Xlib simplified toolkit'
|
7
|
+
s.description = s.name
|
8
|
+
s.homepage = 'https://rubygems.org/gems/uh'
|
9
|
+
|
10
|
+
s.authors = 'Thibault Jouan'
|
11
|
+
s.email = 'tj@a13.fr'
|
12
|
+
|
13
|
+
s.files = `git ls-files`.split $/
|
14
|
+
s.test_files = s.files.grep /\Atest\//
|
15
|
+
|
16
|
+
|
17
|
+
s.add_development_dependency 'rake'
|
18
|
+
s.add_development_dependency 'rake-compiler'
|
19
|
+
s.add_development_dependency 'minitest', '~> 5.5'
|
20
|
+
s.add_development_dependency 'minitest-reporters', '~> 1.0'
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: uh
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Thibault Jouan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake-compiler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest-reporters
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
description: uh
|
70
|
+
email: tj@a13.fr
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- ".gitignore"
|
76
|
+
- Gemfile
|
77
|
+
- Guardfile
|
78
|
+
- Rakefile
|
79
|
+
- TODO
|
80
|
+
- ext/uh/color.c
|
81
|
+
- ext/uh/display.c
|
82
|
+
- ext/uh/event.c
|
83
|
+
- ext/uh/extconf.rb
|
84
|
+
- ext/uh/font.c
|
85
|
+
- ext/uh/pixmap.c
|
86
|
+
- ext/uh/screen.c
|
87
|
+
- ext/uh/uh.c
|
88
|
+
- ext/uh/uh.h
|
89
|
+
- ext/uh/window.c
|
90
|
+
- lib/uh.rb
|
91
|
+
- lib/uh/display.rb
|
92
|
+
- lib/uh/drawable.rb
|
93
|
+
- lib/uh/events.rb
|
94
|
+
- lib/uh/font.rb
|
95
|
+
- lib/uh/geo.rb
|
96
|
+
- lib/uh/pixmap.rb
|
97
|
+
- lib/uh/screen.rb
|
98
|
+
- lib/uh/version.rb
|
99
|
+
- lib/uh/window.rb
|
100
|
+
- lib/uh/wm.rb
|
101
|
+
- lib/uh/wm/action_handler.rb
|
102
|
+
- lib/uh/wm/client.rb
|
103
|
+
- lib/uh/wm/manager.rb
|
104
|
+
- lib/uh/wm/workers/base_worker.rb
|
105
|
+
- lib/uh/wm/workers/blocking_worker.rb
|
106
|
+
- lib/uh/wm/workers/multiplexing_worker.rb
|
107
|
+
- test/test_helper.rb
|
108
|
+
- test/uh/test_geo.rb
|
109
|
+
- uh.gemspec
|
110
|
+
homepage: https://rubygems.org/gems/uh
|
111
|
+
licenses: []
|
112
|
+
metadata: {}
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
requirements: []
|
128
|
+
rubyforge_project:
|
129
|
+
rubygems_version: 2.4.5
|
130
|
+
signing_key:
|
131
|
+
specification_version: 4
|
132
|
+
summary: Xlib simplified toolkit
|
133
|
+
test_files:
|
134
|
+
- test/test_helper.rb
|
135
|
+
- test/uh/test_geo.rb
|
136
|
+
has_rdoc:
|