diff --git a/bin/uhwm b/bin/uhwm index e03193c..562a83f 100755 --- a/bin/uhwm +++ b/bin/uhwm @@ -3,4 +3,3 @@ require 'uh/wm' Uh::WM::CLI.run(ARGV) -sleep 8 diff --git a/features/actions/quit.feature b/features/actions/quit.feature new file mode 100644 index 0000000..40c0839 --- /dev/null +++ b/features/actions/quit.feature @@ -0,0 +1,6 @@ +Feature: quit action + + Scenario: quits on keybing press + Given uhwm is running + When I press the default quit key binding + Then uhwm should terminate successfully diff --git a/features/steps/run_steps.rb b/features/steps/run_steps.rb index e617e27..70e5a56 100644 --- a/features/steps/run_steps.rb +++ b/features/steps/run_steps.rb @@ -4,6 +4,15 @@ def uhwm_run options = nil @interactive = @process = run command.join ' ' end +def uhwm_run_wait_ready + uhwm_run + uhwm_wait_output 'Connected to' +end + +Given /^uhwm is running$/ do + uhwm_run_wait_ready +end + When /^I start uhwm$/ do uhwm_run end @@ -15,3 +24,7 @@ end Then /^the exit status must be (\d+)$/ do |exit_status| assert_exit_status exit_status.to_i end + +Then /^uhwm should terminate successfully$/ do + assert_exit_status 0 +end diff --git a/features/steps/x_steps.rb b/features/steps/x_steps.rb index d7bcd9e..a900916 100644 --- a/features/steps/x_steps.rb +++ b/features/steps/x_steps.rb @@ -1,3 +1,11 @@ +def x_key key + fail "cannot simulate X key `#{key}'" unless system "xdotool key #{key}" +end + +When /^I press the default quit key binding$/ do + x_key 'alt+q' +end + Then /^it must connect to X display$/ do uhwm_wait_output 'Connected to' expect(`sockstat -u`.lines.grep /\s+ruby.+\s+#{@process.pid}/) diff --git a/lib/uh/wm/runner.rb b/lib/uh/wm/runner.rb index f279c9f..849acac 100644 --- a/lib/uh/wm/runner.rb +++ b/lib/uh/wm/runner.rb @@ -4,7 +4,9 @@ module Uh class << self def run env, **options runner = new env, **options + runner.register_event_hooks runner.connect_manager + runner.run_until { runner.stopped? } end end @@ -25,14 +27,26 @@ module Uh @stopped = true end + def register_event_hooks + register_key_bindings_hooks + end + def connect_manager @manager.connect @env.log "Connected to X server" + @manager.grab_key :q end def run_until &block @manager.handle_pending_events until block.call end + + + private + + def register_key_bindings_hooks + @events.on(:key, :q) { stop! } + end end end end diff --git a/spec/uh/wm/cli_spec.rb b/spec/uh/wm/cli_spec.rb index 193ed83..7bf4482 100644 --- a/spec/uh/wm/cli_spec.rb +++ b/spec/uh/wm/cli_spec.rb @@ -15,6 +15,10 @@ module Uh described_class.run arguments, stdout: stdout, stderr: stderr end + # FIXME: remove this hack we currently need to prevent the Runner from + # blocking. + before { allow(Runner).to receive :run } + it 'builds a new CLI with given arguments' do expect(described_class) .to receive(:new).with(arguments, stdout: stdout).and_call_original diff --git a/spec/uh/wm/runner_spec.rb b/spec/uh/wm/runner_spec.rb index 014c795..7f4a65a 100644 --- a/spec/uh/wm/runner_spec.rb +++ b/spec/uh/wm/runner_spec.rb @@ -5,15 +5,23 @@ module Uh subject(:runner) { described_class.new env } describe '.run' do - subject(:run) { described_class.run env } + subject(:run) { described_class.run env, stopped: true } it 'builds a new Runner with given env' do - expect(described_class).to receive(:new).with(env).and_call_original + expect(described_class) + .to receive(:new).with(env, anything).and_call_original + run + end + + it 'registers event hooks' do + runner.stop! + allow(described_class).to receive(:new) { runner } + expect(runner).to receive(:register_event_hooks) run end it 'connects the manager' do - runner + runner.stop! allow(described_class).to receive(:new) { runner } expect(runner).to receive(:connect_manager) run @@ -62,7 +70,19 @@ module Uh end end + describe '#register_event_hooks' do + context 'key bindings' do + it 'registers key bindings event hooks' do + runner.register_event_hooks + expect(runner.events[:key, :q]).not_to be_empty + end + end + end + describe '#connect_manager' do + let(:manager) { instance_spy Manager } + subject(:runner) { described_class.new env, manager: manager } + it 'connects the manager' do expect(runner.manager).to receive :connect runner.connect_manager @@ -72,6 +92,11 @@ module Uh expect(env).to receive(:log).with /connected/i runner.connect_manager end + + it 'tells the manager to grab keys' do + expect(runner.manager).to receive(:grab_key).with :q + runner.connect_manager + end end describe '#run_until' do