Merge branch 'client-killing'
This commit is contained in:
		
							
								
								
									
										11
									
								
								features/actions/kill.feature
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								features/actions/kill.feature
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| Feature: `kill' action keyword | ||||
|  | ||||
|   @icccm_window | ||||
|   Scenario: kills current client | ||||
|     Given uhwm is running with this run control file: | ||||
|       """ | ||||
|       key(:f) { kill_current } | ||||
|       """ | ||||
|     And an ICCCM compliant window is mapped | ||||
|     When I press the alt+f keys | ||||
|     Then the ICCCM window must be unmapped by the manager | ||||
| @@ -1,3 +1,10 @@ | ||||
| Given /^an ICCCM compliant window is mapped$/ do | ||||
|   icccm_window_start | ||||
|   timeout_until 'window not mapped after %d seconds' do | ||||
|     x_window_map_state(icccm_window_name) == 'IsViewable' | ||||
|   end | ||||
| end | ||||
|  | ||||
| Given /^a(?:\s(\w+))? window is mapped$/ do |ident| | ||||
|   x_client(ident).map.sync | ||||
|   timeout_until 'window not mapped after %d seconds' do | ||||
| @@ -42,6 +49,10 @@ Then /^the(?:\s(\w+))? window must be mapped$/ do |ident| | ||||
|   end | ||||
| end | ||||
|  | ||||
| Then /^the ICCCM window must be unmapped by the manager$/ do | ||||
|   uhwm_wait_output /unmanag.+#{icccm_window_name}/i | ||||
| end | ||||
|  | ||||
| Then /^the window must be focused$/ do | ||||
|   timeout_until 'window not focused after %d seconds' do | ||||
|     x_focused_window_id == x_client.window_id | ||||
|   | ||||
| @@ -28,6 +28,10 @@ Around '@other_wm_running' do |_, block| | ||||
|   with_other_wm { block.call } | ||||
| end | ||||
|  | ||||
| After '@icccm_window' do | ||||
|   icccm_window_ensure_stop | ||||
| end | ||||
|  | ||||
| if ENV.key? 'TRAVIS' | ||||
|   ENV['UHWMTEST_TIMEOUT'] = 8.to_s | ||||
| end | ||||
|   | ||||
| @@ -38,6 +38,10 @@ module Uh | ||||
|         Process.waitpid pid | ||||
|       end | ||||
|  | ||||
|       def kill_current | ||||
|         layout.current_client.kill | ||||
|       end | ||||
|  | ||||
|       def log_separator | ||||
|         log '- ' * 24 | ||||
|       end | ||||
|   | ||||
| @@ -66,6 +66,20 @@ module Uh | ||||
|         @window.focus | ||||
|         self | ||||
|       end | ||||
|  | ||||
|       def kill | ||||
|         if @window.icccm_wm_protocols.include? :WM_DELETE_WINDOW | ||||
|           @window.icccm_wm_delete | ||||
|         else | ||||
|           @window.kill | ||||
|         end | ||||
|         self | ||||
|       end | ||||
|  | ||||
|       def kill! | ||||
|         window.kill | ||||
|         self | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -8,6 +8,19 @@ module Uh | ||||
|         QUIT_KEYBINDING = 'alt+shift+q'.freeze | ||||
|         LOG_READY       = 'Working events'.freeze | ||||
|  | ||||
|         def icccm_window_start | ||||
|           @icccm_window = ChildProcess.build(*%w[xmessage window]) | ||||
|           @icccm_window.start | ||||
|         end | ||||
|  | ||||
|         def icccm_window_ensure_stop | ||||
|           @icccm_window.stop | ||||
|         end | ||||
|  | ||||
|         def icccm_window_name | ||||
|           'xmessage' | ||||
|         end | ||||
|  | ||||
|         def uhwm_run options = '-v' | ||||
|           command = %w[uhwm] | ||||
|           command << options if options | ||||
| @@ -89,8 +102,14 @@ expected `#{message}' (#{times}) not seen after #{e.timeout} seconds in: | ||||
|           fail "cannot simulate X key `#{k}'" unless system "xdotool key #{k}" | ||||
|         end | ||||
|  | ||||
|         def x_window_map_state window_id | ||||
|           `xwininfo -id #{window_id}`[/Map State: (\w+)/, 1] | ||||
|         def x_window_map_state window_selector | ||||
|           select_args = case window_selector | ||||
|             when Integer  then "-id #{window_selector}" | ||||
|             when String   then "-name #{window_selector}" | ||||
|             else fail ArgumentError, | ||||
|               "not an Integer nor a String: `#{window_selector.inspect}'" | ||||
|           end | ||||
|           `xwininfo #{select_args} 2> /dev/null`[/Map State: (\w+)/, 1] | ||||
|         end | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -17,11 +17,12 @@ module Factories | ||||
|       modifier_mask:  modifier_mask | ||||
|   end | ||||
|  | ||||
|   def mock_window override_redirect: false | ||||
|   def mock_window override_redirect: false, icccm_wm_protocols: [] | ||||
|     instance_spy Uh::Window, 'window', | ||||
|       to_s:               'wid', | ||||
|       name:               'wname', | ||||
|       wclass:             'wclass', | ||||
|       override_redirect?: override_redirect | ||||
|       override_redirect?: override_redirect, | ||||
|       icccm_wm_protocols: icccm_wm_protocols | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -24,6 +24,21 @@ module Uh | ||||
|         end | ||||
|       end | ||||
|  | ||||
|       describe '#kill_current' do | ||||
|         let(:client) { instance_spy Client } | ||||
|  | ||||
|         context 'when layout has a client' do | ||||
|           before do | ||||
|             allow(actions.layout).to receive(:current_client) { client } | ||||
|           end | ||||
|  | ||||
|           it 'kills layout current client' do | ||||
|             expect(client).to receive :kill | ||||
|             actions.kill_current | ||||
|           end | ||||
|         end | ||||
|       end | ||||
|  | ||||
|       describe '#log_separator' do | ||||
|         it 'logs a separator' do | ||||
|           expect(env).to receive(:log).with /(?:- ){20,}/ | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| module Uh | ||||
|   module WM | ||||
|     RSpec.describe Client do | ||||
|       let(:window)      { mock_window } | ||||
|       let(:protocols)   { [] } | ||||
|       let(:window)      { mock_window icccm_wm_protocols: protocols } | ||||
|       let(:geo)         { build_geo } | ||||
|       subject(:client)  { described_class.new window, geo } | ||||
|  | ||||
| @@ -143,6 +144,37 @@ module Uh | ||||
|           expect(client.focus).to be client | ||||
|         end | ||||
|       end | ||||
|  | ||||
|       describe '#kill' do | ||||
|         it 'kills the window' do | ||||
|           expect(window).to receive :kill | ||||
|           client.kill | ||||
|         end | ||||
|  | ||||
|         it 'returns self' do | ||||
|           expect(client.kill).to be client | ||||
|         end | ||||
|  | ||||
|         context 'when window supports icccm wm delete' do | ||||
|           let(:protocols) { [:WM_DELETE_WINDOW] } | ||||
|  | ||||
|           it 'icccm deletes the window' do | ||||
|             expect(window).to receive :icccm_wm_delete | ||||
|             client.kill | ||||
|           end | ||||
|         end | ||||
|       end | ||||
|  | ||||
|       describe '#kill!' do | ||||
|         it 'kills the window' do | ||||
|           expect(window).to receive :kill | ||||
|           client.kill! | ||||
|         end | ||||
|  | ||||
|         it 'returns self' do | ||||
|           expect(client.kill!).to be client | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|   | ||||
		Reference in New Issue
	
	Block a user