diff --git a/features/manager/unmanage.feature b/features/manager/unmanage.feature index 5851243..04aa073 100644 --- a/features/manager/unmanage.feature +++ b/features/manager/unmanage.feature @@ -1,7 +1,13 @@ Feature: manager client unmanagement - Scenario: logs when a new client is unmanaged + Background: Given uhwm is running And a window is mapped + + Scenario: logs when a new client is unmanaged When the window requests to be unmapped Then the output must match /unmanag.+xclient/i + + Scenario: unmanages client on destroy notify X events + When the window is destroyed + Then the output must match /unmanag.+xclient/i diff --git a/features/steps/x_steps.rb b/features/steps/x_steps.rb index 84629f9..ca19392 100644 --- a/features/steps/x_steps.rb +++ b/features/steps/x_steps.rb @@ -26,6 +26,10 @@ When /^a window requests to be mapped (\d+) times$/ do |times| x_window_map times: times.to_i end +When /^the window is destroyed$/ do + x_window_destroy +end + Then /^it must connect to X display$/ do uhwm_wait_output 'Connected to' expect(x_socket_check uhwm_pid).to be true diff --git a/lib/uh/wm/manager.rb b/lib/uh/wm/manager.rb index ab09703..ab830cd 100644 --- a/lib/uh/wm/manager.rb +++ b/lib/uh/wm/manager.rb @@ -71,6 +71,12 @@ module Uh end end + def destroy window + return unless client = client_for(window) + @clients.delete client + @events.emit :unmanage, args: client + end + def handle_next_event handle @display.next_event end @@ -103,6 +109,10 @@ module Uh configure event.window end + def handle_destroy_notify event + destroy event.window + end + def handle_map_request event map event.window end diff --git a/lib/uh/wm/testing/acceptance_helpers.rb b/lib/uh/wm/testing/acceptance_helpers.rb index 4278e17..d8256f1 100644 --- a/lib/uh/wm/testing/acceptance_helpers.rb +++ b/lib/uh/wm/testing/acceptance_helpers.rb @@ -106,6 +106,11 @@ module Uh x_client(options).sync end + def x_window_destroy **options + x_client(options).destroy + x_client(options).sync + end + def x_clients_ensure_stop @x_clients and @x_clients.any? and @x_clients.values.each &:terminate end @@ -177,6 +182,11 @@ module Uh window.unmap self end + + def destroy + window.destroy + self + end end end end diff --git a/spec/uh/wm/manager_spec.rb b/spec/uh/wm/manager_spec.rb index 3238b09..b3180c8 100644 --- a/spec/uh/wm/manager_spec.rb +++ b/spec/uh/wm/manager_spec.rb @@ -214,6 +214,35 @@ module Uh end end + describe '#destroy' do + before { manager.map window } + + it 'unregisters the client' do + expect { manager.destroy window } + .to change { manager.clients.size }.from(1).to 0 + end + + it 'emits :unmanage event with the client' do + events.on :unmanage, &block + expect(block).to receive(:call).with manager.clients[0] + manager.destroy window + end + + context 'with unknown window' do + let(:unknown_window) { window.dup } + + it 'does not change registered clients' do + expect { manager.destroy unknown_window } + .not_to change { manager.clients } + end + + it 'does not emit any event' do + expect(events).not_to receive :emit + manager.destroy unknown_window + end + end + end + describe '#handle_next_event' do it 'handles the next available event on display' do event = double 'event' @@ -294,6 +323,15 @@ module Uh end end + context 'when destroy_notify event is given' do + let(:event) { double 'event', type: :destroy_notify, window: :window } + + it 'destroy the event window' do + expect(manager).to receive(:destroy).with :window + manager.handle event + end + end + context 'when map_request event is given' do let(:event) { double 'event', type: :map_request, window: :window } diff --git a/uh-wm.gemspec b/uh-wm.gemspec index 1b5766f..8ec6d76 100644 --- a/uh-wm.gemspec +++ b/uh-wm.gemspec @@ -14,7 +14,7 @@ Gem::Specification.new do |s| s.test_files = s.files.grep /\A(spec|features)\// s.executables = s.files.grep(/\Abin\//) { |f| File.basename(f) } - s.add_dependency 'uh', '2.0.0.pre1' + s.add_dependency 'uh', '2.0.0.pre2' s.add_dependency 'uh-layout', '0.2.0.pre' s.add_development_dependency 'aruba', '~> 0.6'