diff --git a/.travis.yml b/.travis.yml index f20fa04..b3cdd69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ rvm: - 2.1 before_install: - sudo apt-get update -qq - - sudo apt-get install -qq xdotool + - sudo apt-get install -qq twm xdotool matrix: allow_failures: - rvm: ruby-head diff --git a/features/manager/check_other_wm.feature b/features/manager/check_other_wm.feature new file mode 100644 index 0000000..3e71a0a --- /dev/null +++ b/features/manager/check_other_wm.feature @@ -0,0 +1,8 @@ +Feature: checking if another window manager is running + + @other_wm_running + Scenario: fails when another window manager is running + Given another window manager is running + When I start uhwm + Then the exit status must be 70 + And the current output must match /error.+other.+window.+manager/i diff --git a/features/steps/output_steps.rb b/features/steps/output_steps.rb index 46fc2d0..bfad39a 100644 --- a/features/steps/output_steps.rb +++ b/features/steps/output_steps.rb @@ -2,7 +2,7 @@ def uhwm_wait_output message, timeout: 1 Timeout.timeout(timeout) do loop do break if case message - when Regexp then @process.read_stdout =~ message + when Regexp then @process.stdout + @process.stderr =~ message when String then assert_partial_output_interactive message end sleep 0.1 @@ -28,6 +28,10 @@ options: eoh end +Then /^the output must match \/([^\/]+)\/([a-z]*)$/ do |pattern, options| + expect(@process.stdout).to match Regexp.new(pattern, options) +end + Then /^the current output must match \/([^\/]+)\/([a-z]*)$/ do |pattern, options| uhwm_wait_output Regexp.new(pattern, options) end diff --git a/features/steps/run_steps.rb b/features/steps/run_steps.rb index 2a85a73..534e20f 100644 --- a/features/steps/run_steps.rb +++ b/features/steps/run_steps.rb @@ -9,6 +9,10 @@ def uhwm_run_wait_ready uhwm_wait_output 'Connected to' end +Given /^another window manager is running$/ do + expect(@other_wm).to be_alive +end + Given /^uhwm is running$/ do uhwm_run_wait_ready end diff --git a/features/support/env.rb b/features/support/env.rb index 1d20ab0..b43e86b 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -14,3 +14,10 @@ Headless.new.start After do |scenario| @process and @process.terminate end + +Around '@other_wm_running' do |scenario, block| + @other_wm = ChildProcess.build('twm') + @other_wm.start + block.call + @other_wm.stop +end diff --git a/lib/uh/wm.rb b/lib/uh/wm.rb index 6b6098a..0b368ee 100644 --- a/lib/uh/wm.rb +++ b/lib/uh/wm.rb @@ -11,8 +11,9 @@ require 'uh/wm/runner' module Uh module WM - Error = Class.new(StandardError) - RuntimeError = Class.new(RuntimeError) - ArgumentError = Class.new(Error) + Error = Class.new(StandardError) + RuntimeError = Class.new(RuntimeError) + ArgumentError = Class.new(Error) + OtherWMRunningError = Class.new(RuntimeError) end end diff --git a/lib/uh/wm/manager.rb b/lib/uh/wm/manager.rb index 3ce8a0b..4a9cb46 100644 --- a/lib/uh/wm/manager.rb +++ b/lib/uh/wm/manager.rb @@ -1,6 +1,8 @@ module Uh module WM class Manager + INPUT_MASK = Events::SUBSTRUCTURE_REDIRECT_MASK + attr_reader :display def initialize events, display = Display.new @@ -11,6 +13,13 @@ module Uh def connect @events.emit :connecting, args: @display @display.open + Display.on_error do + fail OtherWMRunningError, 'another window manager is already running' + end + @display.listen_events INPUT_MASK + @display.sync false + Display.on_error { |*args| handle_error *args } + @display.sync false @events.emit :connected, args: @display end @@ -27,6 +36,13 @@ module Uh when :key_press then @events.emit :key, event.key.to_sym end end + + + private + + def handle_error *args + @dispatcher.emit :error, args: args + end end end end diff --git a/spec/uh/wm/manager_spec.rb b/spec/uh/wm/manager_spec.rb index bd3ae71..00d7a15 100644 --- a/spec/uh/wm/manager_spec.rb +++ b/spec/uh/wm/manager_spec.rb @@ -11,14 +11,11 @@ module Uh end end - describe '#connect' do + describe '#connect', :xvfb do let(:block) { proc { } } - # Prevent Manager to open a real display. - before { allow(display).to receive :open } - it 'opens the display' do - expect(manager.display).to receive :open + expect(manager.display).to receive(:open).and_call_original manager.connect end