uh-wm 0.0.2.pre → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/.travis.yml +15 -0
- data/Gemfile +5 -0
- data/Guardfile +12 -0
- data/LICENSE +30 -0
- data/README.md +68 -0
- data/Rakefile +40 -0
- data/bin/uhwm +5 -0
- data/config/cucumber.yaml +1 -0
- data/features/actions/execute.feature +9 -0
- data/features/actions/layout_delegation.feature +31 -0
- data/features/actions/quit.feature +9 -0
- data/features/cli/debug.feature +5 -0
- data/features/cli/layout.feature +15 -0
- data/features/cli/require.feature +5 -0
- data/features/cli/run_control.feature +9 -0
- data/features/cli/usage.feature +11 -0
- data/features/cli/verbose.feature +5 -0
- data/features/cli/version.feature +6 -0
- data/features/cli/worker.feature +9 -0
- data/features/layout/manage.feature +12 -0
- data/features/layout/protocol.feature +24 -0
- data/features/layout/unmanage.feature +10 -0
- data/features/manager/check_other_wm.feature +8 -0
- data/features/manager/input_events.feature +8 -0
- data/features/manager/manage.feature +14 -0
- data/features/manager/unmanage.feature +13 -0
- data/features/manager/x_errors.feature +17 -0
- data/features/run_control/evaluation.feature +18 -0
- data/features/run_control/key.feature +33 -0
- data/features/run_control/modifier.feature +10 -0
- data/features/run_control/worker.feature +9 -0
- data/features/session/connection.feature +5 -0
- data/features/session/termination.feature +13 -0
- data/features/steps/filesystem_steps.rb +3 -0
- data/features/steps/output_steps.rb +44 -0
- data/features/steps/run_control_steps.rb +3 -0
- data/features/steps/run_steps.rb +41 -0
- data/features/steps/x_steps.rb +53 -0
- data/features/support/env.rb +33 -0
- data/lib/uh/wm.rb +8 -0
- data/lib/uh/wm/actions_handler.rb +46 -0
- data/lib/uh/wm/cli.rb +20 -13
- data/lib/uh/wm/client.rb +64 -0
- data/lib/uh/wm/dispatcher.rb +3 -1
- data/lib/uh/wm/env.rb +15 -9
- data/lib/uh/wm/env_logging.rb +8 -0
- data/lib/uh/wm/logger_formatter.rb +16 -0
- data/lib/uh/wm/manager.rb +96 -14
- data/lib/uh/wm/run_control.rb +8 -3
- data/lib/uh/wm/runner.rb +82 -14
- data/lib/uh/wm/testing/acceptance_helpers.rb +140 -18
- data/lib/uh/wm/version.rb +1 -1
- data/lib/uh/wm/workers.rb +21 -0
- data/lib/uh/wm/workers/base.rb +27 -0
- data/lib/uh/wm/workers/blocking.rb +11 -0
- data/lib/uh/wm/workers/mux.rb +18 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/exit_helpers.rb +6 -0
- data/spec/support/filesystem_helpers.rb +11 -0
- data/spec/uh/wm/actions_handler_spec.rb +30 -0
- data/spec/uh/wm/cli_spec.rb +214 -0
- data/spec/uh/wm/client_spec.rb +133 -0
- data/spec/uh/wm/dispatcher_spec.rb +76 -0
- data/spec/uh/wm/env_spec.rb +145 -0
- data/spec/uh/wm/manager_spec.rb +355 -0
- data/spec/uh/wm/run_control_spec.rb +102 -0
- data/spec/uh/wm/runner_spec.rb +186 -0
- data/uh-wm.gemspec +25 -0
- metadata +112 -9
@@ -0,0 +1,17 @@
|
|
1
|
+
Feature: X errors logging
|
2
|
+
|
3
|
+
Scenario: logs error details
|
4
|
+
Given a file named layout.rb with:
|
5
|
+
"""
|
6
|
+
class Layout
|
7
|
+
def register _; end
|
8
|
+
|
9
|
+
# Focusing a client before mapping will force an error
|
10
|
+
def << client
|
11
|
+
client.focus
|
12
|
+
end
|
13
|
+
end
|
14
|
+
"""
|
15
|
+
And uhwm is running with options -v -r./layout -l Layout
|
16
|
+
When a window requests to be mapped
|
17
|
+
Then the output must match /x.*error.+x_setinputfocus.+/i
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Feature: run control file evaluation
|
2
|
+
|
3
|
+
Scenario: evaluates the default run control file when present
|
4
|
+
Given a run control file with:
|
5
|
+
"""
|
6
|
+
puts 'run control evaluation'
|
7
|
+
"""
|
8
|
+
When I start uhwm
|
9
|
+
Then the output must contain "run control evaluation"
|
10
|
+
|
11
|
+
Scenario: reports run control code in backtrace on errors
|
12
|
+
Given a run control file with:
|
13
|
+
"""
|
14
|
+
'no error on first line'
|
15
|
+
fail 'fails on second line'
|
16
|
+
"""
|
17
|
+
When I start uhwm
|
18
|
+
Then the output must match /\.uhwmrc\.rb:2:.+fails on second line/
|
@@ -0,0 +1,33 @@
|
|
1
|
+
Feature: `key' run control keyword
|
2
|
+
|
3
|
+
Scenario: defines code to run when given key is pressed
|
4
|
+
Given uhwm is running with this run control file:
|
5
|
+
"""
|
6
|
+
key(:f) { puts 'trigger f key code' }
|
7
|
+
"""
|
8
|
+
When I press the alt+f keys
|
9
|
+
Then the output must contain "trigger f key code"
|
10
|
+
|
11
|
+
Scenario: defines code to run when given keys are pressed
|
12
|
+
Given uhwm is running with this run control file:
|
13
|
+
"""
|
14
|
+
key(:f, :shift) { puts 'trigger f key code' }
|
15
|
+
"""
|
16
|
+
When I press the alt+shift+f keys
|
17
|
+
Then the output must contain "trigger f key code"
|
18
|
+
|
19
|
+
Scenario: translates common key names to their X equivalent
|
20
|
+
Given uhwm is running with this run control file:
|
21
|
+
"""
|
22
|
+
key(:enter) { puts 'trigger return key code' }
|
23
|
+
"""
|
24
|
+
When I press the alt+Return keys
|
25
|
+
Then the output must contain "trigger return key code"
|
26
|
+
|
27
|
+
Scenario: translates upcased key names to combination with shift key
|
28
|
+
Given uhwm is running with this run control file:
|
29
|
+
"""
|
30
|
+
key(:F) { puts 'trigger shift+f key code' }
|
31
|
+
"""
|
32
|
+
When I press the alt+shift+f keys
|
33
|
+
Then the output must contain "trigger shift+f key code"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: program termination
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given uhwm is running
|
5
|
+
|
6
|
+
Scenario: terminates on quit request
|
7
|
+
When I tell uhwm to quit
|
8
|
+
Then uhwm must terminate successfully
|
9
|
+
|
10
|
+
Scenario: logs about termination
|
11
|
+
When I tell uhwm to quit
|
12
|
+
Then uhwm must terminate successfully
|
13
|
+
And the output must match /terminat/i
|
@@ -0,0 +1,44 @@
|
|
1
|
+
Then /^the output must contain exactly the usage$/ do
|
2
|
+
assert_exact_output <<-eoh, all_output
|
3
|
+
Usage: uhwm [options]
|
4
|
+
|
5
|
+
options:
|
6
|
+
-v, --verbose enable verbose mode
|
7
|
+
-d, --debug enable debug mode
|
8
|
+
-f, --run-control PATH specify alternate run control file
|
9
|
+
-r, --require PATH require ruby feature
|
10
|
+
-l, --layout LAYOUT specify layout
|
11
|
+
-w, --worker WORKER specify worker
|
12
|
+
|
13
|
+
-h, --help print this message
|
14
|
+
-V, --version print version
|
15
|
+
eoh
|
16
|
+
end
|
17
|
+
|
18
|
+
Then /^the output must contain exactly the version$/ do
|
19
|
+
assert_exact_output "%s\n" % Uh::WM::VERSION, all_output
|
20
|
+
end
|
21
|
+
|
22
|
+
Then /^the output must match \/([^\/]+)\/([a-z]*)$/ do |pattern, options|
|
23
|
+
uhwm_wait_output Regexp.new(pattern, options)
|
24
|
+
end
|
25
|
+
|
26
|
+
Then /^the output must not match \/([^\/]+)\/([a-z]*)$/ do |pattern, options|
|
27
|
+
expect(all_output).not_to match Regexp.new(pattern, options)
|
28
|
+
end
|
29
|
+
|
30
|
+
Then /^the output must contain:$/ do |content|
|
31
|
+
uhwm_wait_output content.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
Then /^the output must contain "([^"]+)"$/ do |content|
|
35
|
+
uhwm_wait_output content.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
Then /^the output must contain current display$/ do
|
39
|
+
uhwm_wait_output ENV['DISPLAY']
|
40
|
+
end
|
41
|
+
|
42
|
+
Then /^the output must contain the window name$/ do
|
43
|
+
uhwm_wait_output x_window_name
|
44
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
Given /^another window manager is running$/ do
|
2
|
+
expect(other_wm).to be_alive
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /^uhwm is running$/ do
|
6
|
+
uhwm_run_wait_ready
|
7
|
+
end
|
8
|
+
|
9
|
+
Given /^uhwm is running with options? (-.+)$/ do |options|
|
10
|
+
uhwm_run_wait_ready options
|
11
|
+
end
|
12
|
+
|
13
|
+
Given /^uhwm is running with this run control file:$/ do |rc|
|
14
|
+
write_file '.uhwmrc.rb', rc
|
15
|
+
uhwm_run_wait_ready
|
16
|
+
end
|
17
|
+
|
18
|
+
When /^I start uhwm$/ do
|
19
|
+
uhwm_run
|
20
|
+
end
|
21
|
+
|
22
|
+
When /^I run uhwm with options? (-.+)$/ do |options|
|
23
|
+
uhwm_run options
|
24
|
+
end
|
25
|
+
|
26
|
+
When /^I tell uhwm to quit$/ do
|
27
|
+
x_key 'alt+shift+q'
|
28
|
+
end
|
29
|
+
|
30
|
+
When /^I quit uhwm$/ do
|
31
|
+
x_key 'alt+shift+q'
|
32
|
+
assert_exit_status 0
|
33
|
+
end
|
34
|
+
|
35
|
+
Then /^the exit status must be (\d+)$/ do |exit_status|
|
36
|
+
assert_exit_status exit_status.to_i
|
37
|
+
end
|
38
|
+
|
39
|
+
Then /^uhwm must terminate successfully$/ do
|
40
|
+
assert_exit_status 0
|
41
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
Given /^a (\w+) window is mapped$/ do |ident|
|
2
|
+
x_window_map ident: ident
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /^a window is managed$/ do
|
6
|
+
x_window_map
|
7
|
+
uhwm_wait_output /manag.+#{x_window_name}/i
|
8
|
+
end
|
9
|
+
|
10
|
+
When /^I press the ([^ ]+) keys?$/ do |keys|
|
11
|
+
x_key keys
|
12
|
+
end
|
13
|
+
|
14
|
+
When /^a window requests to be mapped$/ do
|
15
|
+
x_window_map
|
16
|
+
end
|
17
|
+
|
18
|
+
When /^the window requests to be unmapped$/ do
|
19
|
+
x_window_unmap
|
20
|
+
end
|
21
|
+
|
22
|
+
When /^the (\w+) window requests to be unmapped$/ do |ident|
|
23
|
+
x_window_unmap ident: ident
|
24
|
+
end
|
25
|
+
|
26
|
+
When /^a window requests to be mapped (\d+) times$/ do |times|
|
27
|
+
x_window_map times: times.to_i
|
28
|
+
end
|
29
|
+
|
30
|
+
When /^the window is destroyed$/ do
|
31
|
+
x_window_destroy
|
32
|
+
end
|
33
|
+
|
34
|
+
Then /^it must connect to X display$/ do
|
35
|
+
uhwm_wait_output 'Connected to'
|
36
|
+
expect(x_socket_check uhwm_pid).to be true
|
37
|
+
end
|
38
|
+
|
39
|
+
Then /^the window must be mapped$/ do
|
40
|
+
expect(x_window_map_state).to eq 'IsViewable'
|
41
|
+
end
|
42
|
+
|
43
|
+
Then /^the (\w+) window must be mapped$/ do |ident|
|
44
|
+
expect(x_window_map_state ident: ident).to eq 'IsViewable'
|
45
|
+
end
|
46
|
+
|
47
|
+
Then /^the window must be focused$/ do
|
48
|
+
expect(x_focused_window_id).to eq x_window_id
|
49
|
+
end
|
50
|
+
|
51
|
+
Then /^the input event mask must include (.+)$/ do |mask|
|
52
|
+
expect(x_input_event_masks).to include mask
|
53
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'aruba/cucumber'
|
2
|
+
require 'headless'
|
3
|
+
|
4
|
+
require 'uh/wm/testing/acceptance_helpers'
|
5
|
+
|
6
|
+
module Aruba
|
7
|
+
class SpawnProcess
|
8
|
+
def pid
|
9
|
+
@process.pid
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
World(Uh::WM::Testing::AcceptanceHelpers)
|
15
|
+
|
16
|
+
Headless.new.start
|
17
|
+
|
18
|
+
Before do
|
19
|
+
set_env 'HOME', File.expand_path(current_dir)
|
20
|
+
end
|
21
|
+
|
22
|
+
After do
|
23
|
+
uhwm_ensure_stop
|
24
|
+
x_clients_ensure_stop
|
25
|
+
end
|
26
|
+
|
27
|
+
Around '@other_wm_running' do |_, block|
|
28
|
+
with_other_wm { block.call }
|
29
|
+
end
|
30
|
+
|
31
|
+
if ENV.key? 'TRAVIS'
|
32
|
+
ENV['UHWMTEST_TIMEOUT'] = 8.to_s
|
33
|
+
end
|
data/lib/uh/wm.rb
CHANGED
@@ -3,13 +3,21 @@ require 'logger'
|
|
3
3
|
require 'optparse'
|
4
4
|
require 'uh'
|
5
5
|
|
6
|
+
require 'uh/wm/env_logging'
|
7
|
+
|
6
8
|
require 'uh/wm/actions_handler'
|
7
9
|
require 'uh/wm/cli'
|
10
|
+
require 'uh/wm/client'
|
8
11
|
require 'uh/wm/dispatcher'
|
9
12
|
require 'uh/wm/env'
|
13
|
+
require 'uh/wm/logger_formatter'
|
10
14
|
require 'uh/wm/manager'
|
11
15
|
require 'uh/wm/run_control'
|
12
16
|
require 'uh/wm/runner'
|
17
|
+
require 'uh/wm/workers'
|
18
|
+
require 'uh/wm/workers/base'
|
19
|
+
require 'uh/wm/workers/blocking'
|
20
|
+
require 'uh/wm/workers/mux'
|
13
21
|
|
14
22
|
module Uh
|
15
23
|
module WM
|
@@ -1,6 +1,11 @@
|
|
1
1
|
module Uh
|
2
2
|
module WM
|
3
3
|
class ActionsHandler
|
4
|
+
include EnvLogging
|
5
|
+
|
6
|
+
extend Forwardable
|
7
|
+
def_delegator :@env, :layout
|
8
|
+
|
4
9
|
def initialize env, events
|
5
10
|
@env, @events = env, events
|
6
11
|
end
|
@@ -10,8 +15,49 @@ module Uh
|
|
10
15
|
end
|
11
16
|
|
12
17
|
def quit
|
18
|
+
log 'Quit requested'
|
13
19
|
@events.emit :quit
|
14
20
|
end
|
21
|
+
|
22
|
+
def execute command
|
23
|
+
log "Execute: #{command}"
|
24
|
+
pid = fork do
|
25
|
+
fork do
|
26
|
+
Process.setsid
|
27
|
+
begin
|
28
|
+
exec command
|
29
|
+
rescue Errno::ENOENT => e
|
30
|
+
log_error "ExecuteError: #{e}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
Process.waitpid pid
|
35
|
+
end
|
36
|
+
|
37
|
+
def method_missing(m, *args, &block)
|
38
|
+
if respond_to? m
|
39
|
+
meth = layout_method m
|
40
|
+
log "#{layout.class.name}##{meth} #{args.inspect}"
|
41
|
+
begin
|
42
|
+
layout.send(meth, *args)
|
43
|
+
rescue NoMethodError
|
44
|
+
log_error "Layout does not implement `#{meth}'"
|
45
|
+
end
|
46
|
+
else
|
47
|
+
super
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def respond_to_missing?(m, *)
|
52
|
+
m.to_s =~ /\Alayout_/ || super
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def layout_method(m)
|
59
|
+
m.to_s.gsub(/\Alayout_/, 'handle_').to_sym
|
60
|
+
end
|
15
61
|
end
|
16
62
|
end
|
17
63
|
end
|
data/lib/uh/wm/cli.rb
CHANGED
@@ -3,6 +3,8 @@ module Uh
|
|
3
3
|
class CLI
|
4
4
|
ArgumentError = Class.new(ArgumentError)
|
5
5
|
|
6
|
+
include EnvLogging
|
7
|
+
|
6
8
|
USAGE = "Usage: #{File.basename $0} [options]".freeze
|
7
9
|
|
8
10
|
EX_USAGE = 64
|
@@ -49,33 +51,38 @@ module Uh
|
|
49
51
|
opts.separator ''
|
50
52
|
opts.separator 'options:'
|
51
53
|
|
52
|
-
opts.on '-
|
53
|
-
@env.print opts
|
54
|
-
exit
|
55
|
-
end
|
56
|
-
|
57
|
-
opts.on '-v', '--version', 'enable verbose mode' do
|
54
|
+
opts.on '-v', '--verbose', 'enable verbose mode' do
|
58
55
|
@env.verbose = true
|
59
56
|
@env.log_logger_level
|
60
57
|
end
|
61
|
-
|
62
58
|
opts.on '-d', '--debug', 'enable debug mode' do
|
63
59
|
@env.debug = true
|
64
60
|
@env.log_logger_level
|
65
61
|
end
|
66
|
-
|
67
62
|
opts.on '-f', '--run-control PATH',
|
68
|
-
|
63
|
+
'specify alternate run control file' do |e|
|
69
64
|
@env.rc_path = e
|
70
65
|
end
|
71
|
-
|
72
66
|
opts.on '-r', '--require PATH', 'require ruby feature' do |feature|
|
73
67
|
require feature
|
74
|
-
|
68
|
+
log "Loaded `#{feature}' ruby feature"
|
75
69
|
end
|
76
|
-
|
77
70
|
opts.on '-l', '--layout LAYOUT', 'specify layout' do |layout|
|
78
|
-
@env.layout_class =
|
71
|
+
@env.layout_class = Object.const_get layout.to_sym
|
72
|
+
end
|
73
|
+
opts.on '-w', Workers.types, '--worker WORKER',
|
74
|
+
'specify worker' do |worker|
|
75
|
+
@env.worker = worker.to_sym
|
76
|
+
end
|
77
|
+
|
78
|
+
opts.separator ''
|
79
|
+
opts.on_tail '-h', '--help', 'print this message' do
|
80
|
+
@env.print opts
|
81
|
+
exit
|
82
|
+
end
|
83
|
+
opts.on_tail '-V', '--version', 'print version' do
|
84
|
+
@env.puts VERSION
|
85
|
+
exit
|
79
86
|
end
|
80
87
|
end
|
81
88
|
end
|