fusuma-plugin-wmctrl 0.3.0 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2539c743a8db6735904353675fd05f91d09e5d264a849badb9d6482407bc21ab
4
- data.tar.gz: ec4941b7f2ed5271cbb0920c07733503e2339ccf07d4b8706ff553ce547c54b4
3
+ metadata.gz: c8654418db5d6e428e786f5d8632ba00a302a2a4fc9cc78c89cbcdaca5dd12a2
4
+ data.tar.gz: d12bb4124ad144c82e3c30302d60a64261e7f612e783a6cb26e50ded61f90d51
5
5
  SHA512:
6
- metadata.gz: 754d2fe9d62cd2df08a99bb9fc16ffd32db2e6e92cd8de4005b4d341634c5dfa20610ff19308f18db1e48ce0c2d9fb1bccd56afb1b1df5502ed2864ba11409eb
7
- data.tar.gz: 472916ac385ec8b18f2410f5820d7e0a7543d97b43827268df8e8f740bb007ff16fffd41945ac35a6c12e51506203a8bbf01d2faa1883b13ddbf189a0abfaf42
6
+ metadata.gz: 902bfc1063f1a23f5a0ad03420998ef7e04b51f0e5e9f31dc1c7674d9f676ec40741311d8442642639a834ec421766d5b47b57ab206ca140470348339692eb51
7
+ data.tar.gz: 931711256a8f0a853f35352b018dab803f4fe5cc81637e5796a2d0c5ba30b7274680835d2a026cacef4c2d39db4e174065d7c9f6b526301385b449d1be7ebaac
data/README.md CHANGED
@@ -10,17 +10,31 @@ Window Manager plugin for [Fusuma](https://github.com/iberianpig/fusuma)
10
10
 
11
11
  Run the following code in your terminal.
12
12
 
13
- ### Install wmctrl
13
+ ### 1.Install wmctrl
14
+
15
+ #### For Debian Based Distros (Ubuntu, Debian, Mint, Pop!_OS)
14
16
 
15
17
  ```
16
- $ sudo apt install wmctrl
18
+ $ sudo apt install wmctrl -y
17
19
  ```
18
- ### Install fusuma-plugin-wmctrl
20
+
21
+ #### For Arch Based Distros (Manjaro, Arch)
22
+
23
+ ```
24
+ sudo pacman -S wmctrl
25
+ ```
26
+
27
+ ### 2. Install fusuma-plugin-wmctrl
19
28
 
20
29
  This plugin requires [Fusuma](https://github.com/iberianpig/fusuma#update) version 1.0 or later.
21
30
 
31
+
32
+ **Note For Arch Based Distros:** By default in Arch Linux, when running ```gem```, gems are installed per-user (into ```~/.gem/ruby/```), instead of system-wide (into ```/usr/lib/ruby/gems/```). This is considered the best way to manage gems on Arch, because otherwise they might interfere with gems installed by Pacman. (From Arch Wiki)
33
+
34
+ To install gems system-wide, see any of the methods listed on [Arch Wiki](https://wiki.archlinux.org/index.php/ruby#Installing_gems_system-wide)
35
+
22
36
  ```sh
23
- $ gem install fusuma-plugin-wmctrl
37
+ $ sudo gem install fusuma-plugin-wmctrl
24
38
  ```
25
39
 
26
40
  ## Properties
@@ -33,13 +47,53 @@ Values following are available for `workspace`.
33
47
  * `prev` is value to switch current workspace to previous workspace.
34
48
  * `next` is value to switch current workspace to next workspace.
35
49
 
36
- ### `window:` property for moving active window
50
+ ### `window:` property
37
51
  Add `window:` property in `~/.config/fusuma/config.yml`.
38
52
 
39
53
  Values following are available for `window`.
40
54
 
41
55
  * `prev` is value to move active window to previous workspace.
42
56
  * `next` is value to move active window to next workspace.
57
+ * `fullscreen` is value to toggle fullscreen
58
+ * `fullscreen: toggle` toggles the active window to fullscreen.
59
+ ```yml
60
+ window: fullscreen
61
+ # ↑ same ↓
62
+ window:
63
+ fullscreen: toggle
64
+ ```
65
+
66
+ * `fullscreen: add` changes the active window to a fullscreen.
67
+ ```yml
68
+ window:
69
+ fullscreen: add
70
+ ```
71
+
72
+ * `fullscreen: remove` restores the active window from fullscreen.
73
+ ```yml
74
+ window:
75
+ fullscreen: remove
76
+ ```
77
+ * `maximized` is value to toggle maximized
78
+ * `maximized: toggle` toggles the active window to maximized.
79
+ ```yml
80
+ window: maximized
81
+ # ↑ same ↓
82
+ window:
83
+ maximized: toggle
84
+ ```
85
+
86
+ * `maximized: add` changes the active window to a maximized.
87
+ ```yml
88
+ window:
89
+ maximized: add
90
+ ```
91
+
92
+ * `maximized: remove` restores the active window from maximized.
93
+ ```yml
94
+ window:
95
+ maximized: remove
96
+ ```
43
97
 
44
98
 
45
99
  ## Example
@@ -55,6 +109,17 @@ swipe:
55
109
  workspace: 'prev'
56
110
  ```
57
111
 
112
+ ## Configuration
113
+
114
+ The plugin allows to enable (disabled by default) circular navigation between workspaces. To enable it set the following in your config file `~/.config/fusuma/config.yml`.
115
+
116
+ ```yaml
117
+ plugin:
118
+ executors:
119
+ wmctrl_executor:
120
+ wrap-navigation: true
121
+ ```
122
+
58
123
 
59
124
  ## Contributing
60
125
 
@@ -16,25 +16,12 @@ Gem::Specification.new do |spec|
16
16
  spec.license = 'MIT'
17
17
 
18
18
  # Specify which files should be added to the gem when it is released.
19
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
21
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
- end
19
+ spec.files = Dir['{bin,lib,exe}/**/*', 'LICENSE*', 'README*', '*.gemspec']
20
+ spec.test_files = Dir['{test,spec,features}/**/*']
23
21
  spec.bindir = 'exe'
24
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
23
  spec.require_paths = ['lib']
26
24
 
27
25
  spec.required_ruby_version = '>= 2.3' # https://packages.ubuntu.com/search?keywords=ruby&searchon=names&exact=1&suite=all&section=main
28
- spec.add_dependency 'fusuma', '~> 1.3'
29
-
30
- spec.add_development_dependency 'bundler'
31
- spec.add_development_dependency 'github_changelog_generator', '~> 1.14'
32
- spec.add_development_dependency 'pry-byebug', '~> 3.4'
33
- spec.add_development_dependency 'pry-doc'
34
- spec.add_development_dependency 'pry-inline'
35
- spec.add_development_dependency 'rake', '~> 13.0'
36
- spec.add_development_dependency 'reek'
37
- spec.add_development_dependency 'rspec', '~> 3.0'
38
- spec.add_development_dependency 'rubocop'
39
- spec.add_development_dependency 'yard'
26
+ spec.add_dependency 'fusuma', '~> 2.0.0'
40
27
  end
@@ -1,10 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'posix/spawn'
4
+ require 'singleton'
5
+
3
6
  module Fusuma
4
7
  module Plugin
5
8
  module Executors
6
9
  # Control Window or Workspaces by executing wctrl
7
10
  class WmctrlExecutor < Executor
11
+ # executor properties on config.yml
12
+ # @return [Array<Symbol>]
13
+ def execute_keys
14
+ %i[workspace window]
15
+ end
16
+
17
+ def config_param_types
18
+ {
19
+ 'wrap-navigation': [TrueClass, FalseClass]
20
+ }
21
+ end
22
+
23
+ def initialize
24
+ super()
25
+ Workspace.configure(wrap_navigation: config_params(:'wrap-navigation'))
26
+ end
27
+
8
28
  # execute wmctrl command
9
29
  # @param event [Event]
10
30
  # @return [nil]
@@ -12,11 +32,7 @@ module Fusuma
12
32
  return if search_command(event).nil?
13
33
 
14
34
  MultiLogger.info(wmctrl: search_command(event))
15
- pid = fork do
16
- Process.daemon(true)
17
- exec(search_command(event))
18
- end
19
-
35
+ pid = POSIX::Spawn.spawn(search_command(event))
20
36
  Process.detach(pid)
21
37
  end
22
38
 
@@ -76,25 +92,64 @@ module Fusuma
76
92
 
77
93
  # Manage workspace
78
94
  class Workspace
95
+ include Singleton
96
+
97
+ attr_accessor :wrap_navigation
98
+
79
99
  class << self
80
- # get workspace number
100
+ # configure properties of the workspace switcher
101
+ # @return [NilClass]
102
+ def configure(wrap_navigation:)
103
+ instance.wrap_navigation = wrap_navigation
104
+ end
105
+
106
+ # get next workspace number
81
107
  # @return [Integer]
82
- def current_workspace_num
83
- text = `wmctrl -d`.split("\n").grep(/\*/).first
84
- text.chars.first.to_i
108
+ def next_workspace_num(step:)
109
+ current_workspace_num, total_workspace_num = workspace_values
110
+
111
+ next_workspace_num = current_workspace_num + step
112
+
113
+ return next_workspace_num unless instance.wrap_navigation
114
+
115
+ if next_workspace_num.negative?
116
+ next_workspace_num = total_workspace_num - 1
117
+ elsif next_workspace_num >= total_workspace_num
118
+ next_workspace_num = 0
119
+ else
120
+ next_workspace_num
121
+ end
85
122
  end
86
123
 
87
124
  def move_command(direction:)
88
125
  workspace_num = case direction
89
126
  when 'next'
90
- current_workspace_num + 1
127
+ next_workspace_num(step: 1)
91
128
  when 'prev'
92
- current_workspace_num - 1
129
+ next_workspace_num(step: -1)
93
130
  else
94
131
  raise "#{direction} is invalid key"
95
132
  end
96
133
  "wmctrl -s #{workspace_num}"
97
134
  end
135
+
136
+ private
137
+
138
+ # get current workspace and total workspace numbers
139
+ # @return [Integer, Integer]
140
+ def workspace_values
141
+ wmctrl_output = `wmctrl -d`.split("\n")
142
+
143
+ current_line = wmctrl_output.grep(/\*/).first
144
+ # NOTE: stderror when failed to get desktop
145
+ # `Cannot get current desktop properties. (_NET_CURRENT_DESKTOP or _WIN_WORKSPACE property)`
146
+ return [0, 1] if current_line.nil?
147
+
148
+ current_workspace_num = current_line.chars.first.to_i
149
+ total_workspace_num = wmctrl_output.length
150
+
151
+ [current_workspace_num, total_workspace_num]
152
+ end
98
153
  end
99
154
  end
100
155
 
@@ -118,9 +173,9 @@ module Fusuma
118
173
  def move_command(direction:)
119
174
  workspace_num = case direction
120
175
  when 'next'
121
- Workspace.current_workspace_num + 1
176
+ Workspace.next_workspace_num(step: 1)
122
177
  when 'prev'
123
- Workspace.current_workspace_num - 1
178
+ Workspace.next_workspace_num(step: -1)
124
179
  else
125
180
  raise "#{direction} is invalid key"
126
181
  end
@@ -3,7 +3,7 @@
3
3
  module Fusuma
4
4
  module Plugin
5
5
  module Wmctrl
6
- VERSION = '0.3.0'
6
+ VERSION = '0.4.2'
7
7
  end
8
8
  end
9
9
  end
@@ -0,0 +1,473 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'fusuma/plugin/executors/executor'
6
+ require 'fusuma/plugin/events/event'
7
+ require 'fusuma/plugin/events/records/index_record'
8
+
9
+ require './lib/fusuma/plugin/executors/wmctrl_executor'
10
+
11
+ module Fusuma
12
+ module Plugin
13
+ module Executors
14
+ RSpec.describe WmctrlExecutor do
15
+ before do
16
+ index = Config::Index.new([:dummy, 1, :direction])
17
+ record = Events::Records::IndexRecord.new(index: index)
18
+ @event = Events::Event.new(tag: 'dummy_detector', record: record)
19
+ @executor = WmctrlExecutor.new
20
+
21
+ @default_workspace_num = 1
22
+ allow(WmctrlExecutor::Workspace)
23
+ .to receive(:workspace_values)
24
+ .and_return(@default_workspace_num)
25
+ end
26
+
27
+ around do |example|
28
+ ConfigHelper.load_config_yml = <<~CONFIG
29
+ dummy:
30
+ 1:
31
+ direction:
32
+ workspace: 'prev'
33
+ CONFIG
34
+
35
+ example.run
36
+
37
+ Config.custom_path = nil
38
+ end
39
+
40
+ describe '#execute' do
41
+ it 'detach' do
42
+ pid = rand(20)
43
+ allow(POSIX::Spawn)
44
+ .to receive(:spawn).with(@executor.search_command(@event))
45
+ .and_return pid
46
+
47
+ expect(Process).to receive(:detach).with(pid)
48
+
49
+ @executor.execute(@event)
50
+ end
51
+ end
52
+
53
+ describe '#executable?' do
54
+ context 'when given valid event tagged as xxxx_detector' do
55
+ it { expect(@executor.executable?(@event)).to be_truthy }
56
+ end
57
+
58
+ context 'when given INVALID event tagged as invalid_tag' do
59
+ before do
60
+ @event.tag = 'invalid_tag'
61
+ end
62
+ it { expect(@executor.executable?(@event)).to be_falsey }
63
+ end
64
+ end
65
+
66
+ describe '#search_command' do
67
+ context "when workspace: 'prev'" do
68
+ around do |example|
69
+ ConfigHelper.load_config_yml = <<~CONFIG
70
+ dummy:
71
+ 1:
72
+ direction:
73
+ workspace: 'prev'
74
+ CONFIG
75
+
76
+ example.run
77
+
78
+ Config.custom_path = nil
79
+ end
80
+
81
+ it 'should return wmctrl command' do
82
+ expect(@executor.search_command(@event))
83
+ .to match(/wmctrl -s #{@default_workspace_num - 1}/)
84
+ end
85
+ end
86
+
87
+ context "when workspace: 'next'" do
88
+ around do |example|
89
+ ConfigHelper.load_config_yml = <<~CONFIG
90
+ dummy:
91
+ 1:
92
+ direction:
93
+ workspace: 'next'
94
+ CONFIG
95
+
96
+ example.run
97
+
98
+ Config.custom_path = nil
99
+ end
100
+
101
+ it 'should return wmctrl command' do
102
+ expect(@executor.search_command(@event))
103
+ .to match(/wmctrl -s #{@default_workspace_num + 1}/)
104
+ end
105
+ end
106
+
107
+ context "when window: 'prev'" do
108
+ around do |example|
109
+ ConfigHelper.load_config_yml = <<~CONFIG
110
+ dummy:
111
+ 1:
112
+ direction:
113
+ window: 'prev'
114
+ CONFIG
115
+
116
+ example.run
117
+
118
+ Config.custom_path = nil
119
+ end
120
+
121
+ it 'should return wmctrl command' do
122
+ expect(@executor.search_command(@event))
123
+ .to match(/wmctrl -r :ACTIVE: -t #{@default_workspace_num - 1}/)
124
+ expect(@executor.search_command(@event))
125
+ .to match(/wmctrl -s #{@default_workspace_num - 1}/)
126
+ end
127
+ end
128
+
129
+ context "when window: 'next'" do
130
+ around do |example|
131
+ ConfigHelper.load_config_yml = <<~CONFIG
132
+ dummy:
133
+ 1:
134
+ direction:
135
+ window: 'next'
136
+ CONFIG
137
+
138
+ example.run
139
+
140
+ Config.custom_path = nil
141
+ end
142
+
143
+ it 'should return wmctrl command' do
144
+ expect(@executor.search_command(@event))
145
+ .to match(/wmctrl -r :ACTIVE: -t #{@default_workspace_num + 1}/)
146
+ expect(@executor.search_command(@event))
147
+ .to match(/wmctrl -s #{@default_workspace_num + 1}/)
148
+ end
149
+ end
150
+
151
+ context "when window: 'fullscreen'" do
152
+ around do |example|
153
+ ConfigHelper.load_config_yml = <<~CONFIG
154
+ dummy:
155
+ 1:
156
+ direction:
157
+ window: 'fullscreen'
158
+ CONFIG
159
+
160
+ example.run
161
+
162
+ Config.custom_path = nil
163
+ end
164
+
165
+ it 'should return wmctrl command' do
166
+ expect(@executor.search_command(@event))
167
+ .to match(/wmctrl -r :ACTIVE: -b toggle,fullscreen/)
168
+ end
169
+ end
170
+
171
+ context 'when window: [fullscreen: something]' do
172
+ context "when fullscreen: 'toggle'" do
173
+ around do |example|
174
+ ConfigHelper.load_config_yml = <<~CONFIG
175
+ dummy:
176
+ 1:
177
+ direction:
178
+ window:
179
+ fullscreen: 'toggle'
180
+ CONFIG
181
+
182
+ example.run
183
+
184
+ Config.custom_path = nil
185
+ end
186
+
187
+ it 'should return wmctrl command' do
188
+ expect(@executor.search_command(@event))
189
+ .to match(/wmctrl -r :ACTIVE: -b toggle,fullscreen/)
190
+ end
191
+ end
192
+
193
+ context "when fullscreen: 'add'" do
194
+ around do |example|
195
+ ConfigHelper.load_config_yml = <<~CONFIG
196
+ dummy:
197
+ 1:
198
+ direction:
199
+ window:
200
+ fullscreen: 'add'
201
+ CONFIG
202
+
203
+ example.run
204
+
205
+ Config.custom_path = nil
206
+ end
207
+
208
+ it 'should return wmctrl command' do
209
+ expect(@executor.search_command(@event))
210
+ .to match(/wmctrl -r :ACTIVE: -b add,fullscreen/)
211
+ end
212
+ end
213
+
214
+ context "when fullscreen: 'remove'" do
215
+ around do |example|
216
+ ConfigHelper.load_config_yml = <<~CONFIG
217
+ dummy:
218
+ 1:
219
+ direction:
220
+ window:
221
+ fullscreen: 'remove'
222
+ CONFIG
223
+
224
+ example.run
225
+
226
+ Config.custom_path = nil
227
+ end
228
+
229
+ it 'should return wmctrl command' do
230
+ expect(@executor.search_command(@event))
231
+ .to match(/wmctrl -r :ACTIVE: -b remove,fullscreen/)
232
+ end
233
+ end
234
+ end
235
+
236
+ context "when window: 'maximized'" do
237
+ around do |example|
238
+ ConfigHelper.load_config_yml = <<~CONFIG
239
+ dummy:
240
+ 1:
241
+ direction:
242
+ window: 'maximized'
243
+ CONFIG
244
+
245
+ example.run
246
+
247
+ Config.custom_path = nil
248
+ end
249
+
250
+ it 'should return wmctrl command' do
251
+ expect(@executor.search_command(@event))
252
+ .to match(/wmctrl -r :ACTIVE: -b toggle,maximized/)
253
+ end
254
+ end
255
+
256
+ context 'when window: [maximized: something]' do
257
+ context "when maximized: 'toggle'" do
258
+ around do |example|
259
+ ConfigHelper.load_config_yml = <<~CONFIG
260
+ dummy:
261
+ 1:
262
+ direction:
263
+ window:
264
+ maximized: 'toggle'
265
+ CONFIG
266
+
267
+ example.run
268
+
269
+ Config.custom_path = nil
270
+ end
271
+
272
+ it 'should return wmctrl command' do
273
+ expect(@executor.search_command(@event))
274
+ .to match(/wmctrl -r :ACTIVE: -b toggle,maximized/)
275
+ end
276
+ end
277
+
278
+ context "when maximized: 'add'" do
279
+ around do |example|
280
+ ConfigHelper.load_config_yml = <<~CONFIG
281
+ dummy:
282
+ 1:
283
+ direction:
284
+ window:
285
+ maximized: 'add'
286
+ CONFIG
287
+
288
+ example.run
289
+
290
+ Config.custom_path = nil
291
+ end
292
+
293
+ it 'should return wmctrl command' do
294
+ expect(@executor.search_command(@event))
295
+ .to match(/wmctrl -r :ACTIVE: -b add,maximized/)
296
+ end
297
+ end
298
+
299
+ context "when maximized: 'remove'" do
300
+ around do |example|
301
+ ConfigHelper.load_config_yml = <<~CONFIG
302
+ dummy:
303
+ 1:
304
+ direction:
305
+ window:
306
+ maximized: 'remove'
307
+ CONFIG
308
+
309
+ example.run
310
+
311
+ Config.custom_path = nil
312
+ end
313
+
314
+ it 'should return wmctrl command' do
315
+ expect(@executor.search_command(@event))
316
+ .to match(/wmctrl -r :ACTIVE: -b remove,maximized/)
317
+ end
318
+ end
319
+ end
320
+ context "when window: 'close'" do
321
+ around do |example|
322
+ ConfigHelper.load_config_yml = <<~CONFIG
323
+ dummy:
324
+ 1:
325
+ direction:
326
+ window: 'close'
327
+ CONFIG
328
+
329
+ example.run
330
+
331
+ Config.custom_path = nil
332
+ end
333
+
334
+ it 'should return wmctrl command' do
335
+ expect(@executor.search_command(@event))
336
+ .to match(/wmctrl -c :ACTIVE:/)
337
+ end
338
+ end
339
+
340
+ describe 'wrap_navigation: true' do
341
+ context "when workspace: 'prev' and current workspace 0" do
342
+ around do |example|
343
+ ConfigHelper.load_config_yml = <<~CONFIG
344
+ dummy:
345
+ 1:
346
+ direction:
347
+ workspace: 'prev'
348
+ plugin:
349
+ executors:
350
+ wmctrl_executor:
351
+ wrap-navigation: true
352
+ CONFIG
353
+
354
+ example.run
355
+
356
+ Config.custom_path = nil
357
+ end
358
+
359
+ it 'should return wmctrl command with an index last workspace' do
360
+ current_workspace = 0
361
+ total_workspaces = 3
362
+
363
+ allow(WmctrlExecutor::Workspace)
364
+ .to receive(:workspace_values)
365
+ .and_return([current_workspace, total_workspaces])
366
+
367
+ expect(@executor.search_command(@event))
368
+ .to match(/wmctrl -s #{total_workspaces - 1}/)
369
+ end
370
+ end
371
+
372
+ context "when workspace: 'next' and current workspace = total - 1" do
373
+ around do |example|
374
+ ConfigHelper.load_config_yml = <<~CONFIG
375
+ dummy:
376
+ 1:
377
+ direction:
378
+ workspace: 'next'
379
+ plugin:
380
+ executors:
381
+ wmctrl_executor:
382
+ wrap-navigation: true
383
+ CONFIG
384
+
385
+ example.run
386
+
387
+ Config.custom_path = nil
388
+ end
389
+
390
+ it 'should return wmctrl command with an index of first workspace' do
391
+ current_workspace = 3
392
+ total_workspaces = 4
393
+
394
+ allow(WmctrlExecutor::Workspace)
395
+ .to receive(:workspace_values)
396
+ .and_return([current_workspace, total_workspaces])
397
+
398
+ expect(@executor.search_command(@event))
399
+ .to match(/wmctrl -s 0/)
400
+ end
401
+ end
402
+
403
+ context "when window: 'prev' and current workspace has index 0" do
404
+ around do |example|
405
+ ConfigHelper.load_config_yml = <<~CONFIG
406
+ dummy:
407
+ 1:
408
+ direction:
409
+ window: 'prev'
410
+ plugin:
411
+ executors:
412
+ wmctrl_executor:
413
+ wrap-navigation: true
414
+ CONFIG
415
+
416
+ example.run
417
+
418
+ Config.custom_path = nil
419
+ end
420
+
421
+ it 'should return wmctrl command with index of last workspace' do
422
+ current_workspace = 0
423
+ total_workspaces = 5
424
+
425
+ allow(WmctrlExecutor::Workspace)
426
+ .to receive(:workspace_values)
427
+ .and_return([current_workspace, total_workspaces])
428
+
429
+ expect(@executor.search_command(@event))
430
+ .to match(/wmctrl -r :ACTIVE: -t #{total_workspaces - 1}/)
431
+ expect(@executor.search_command(@event))
432
+ .to match(/wmctrl -s #{total_workspaces - 1}/)
433
+ end
434
+ end
435
+
436
+ context "when window: 'next' and current workspace is last" do
437
+ around do |example|
438
+ ConfigHelper.load_config_yml = <<~CONFIG
439
+ dummy:
440
+ 1:
441
+ direction:
442
+ window: 'next'
443
+ plugin:
444
+ executors:
445
+ wmctrl_executor:
446
+ wrap-navigation: true
447
+ CONFIG
448
+
449
+ example.run
450
+
451
+ Config.custom_path = nil
452
+ end
453
+
454
+ it 'should return wmctrl command with index of first workspace' do
455
+ current_workspace = 4
456
+ total_workspaces = 5
457
+
458
+ allow(WmctrlExecutor::Workspace)
459
+ .to receive(:workspace_values)
460
+ .and_return([current_workspace, total_workspaces])
461
+
462
+ expect(@executor.search_command(@event))
463
+ .to match(/wmctrl -r :ACTIVE: -t 0/)
464
+ expect(@executor.search_command(@event))
465
+ .to match(/wmctrl -s 0/)
466
+ end
467
+ end
468
+ end
469
+ end
470
+ end
471
+ end
472
+ end
473
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Fusuma::Plugin::Wmctrl do
6
+ it 'has a version number' do
7
+ expect(Fusuma::Plugin::Wmctrl::VERSION).not_to be nil
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tempfile'
4
+ require 'fusuma/config'
5
+
6
+ module Fusuma
7
+ module ConfigHelper
8
+ module_function
9
+
10
+ def load_config_yml=(string)
11
+ Config.custom_path = Tempfile.open do |temp_file|
12
+ temp_file.tap { |f| f.write(string) }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'helpers/config_helper'
5
+
6
+ RSpec.configure do |config|
7
+ # Enable flags like --only-failures and --next-failure
8
+ config.example_status_persistence_file_path = '.rspec_status'
9
+
10
+ # Disable RSpec exposing methods globally on `Module` and `main`
11
+ config.disable_monkey_patching!
12
+
13
+ config.expect_with :rspec do |c|
14
+ c.syntax = :expect
15
+ end
16
+
17
+ config.include(Fusuma::ConfigHelper)
18
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fusuma-plugin-wmctrl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - iberianpig
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-03 00:00:00.000000000 Z
11
+ date: 2021-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fusuma
@@ -16,154 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: 2.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.3'
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: github_changelog_generator
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '1.14'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '1.14'
55
- - !ruby/object:Gem::Dependency
56
- name: pry-byebug
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '3.4'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '3.4'
69
- - !ruby/object:Gem::Dependency
70
- name: pry-doc
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: pry-inline
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: rake
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '13.0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '13.0'
111
- - !ruby/object:Gem::Dependency
112
- name: reek
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: rspec
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '3.0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '3.0'
139
- - !ruby/object:Gem::Dependency
140
- name: rubocop
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
- - !ruby/object:Gem::Dependency
154
- name: yard
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: '0'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - ">="
165
- - !ruby/object:Gem::Version
166
- version: '0'
26
+ version: 2.0.0
167
27
  description: fusuma-plugin-wmctrl is Fusuma plugin for window manager.
168
28
  email:
169
29
  - yhkyky@gmail.com
@@ -171,23 +31,18 @@ executables: []
171
31
  extensions: []
172
32
  extra_rdoc_files: []
173
33
  files:
174
- - ".gitignore"
175
- - ".rspec"
176
- - ".rubocop.yml"
177
- - ".rubocop_todo.yml"
178
- - ".travis.yml"
179
- - CHANGELOG.md
180
- - CODE_OF_CONDUCT.md
181
- - Gemfile
182
34
  - LICENSE.txt
183
35
  - README.md
184
- - Rakefile
185
36
  - bin/console
186
37
  - bin/setup
187
38
  - fusuma-plugin-wmctrl.gemspec
188
39
  - lib/fusuma/plugin/executors/wmctrl_executor.rb
189
40
  - lib/fusuma/plugin/wmctrl.rb
190
41
  - lib/fusuma/plugin/wmctrl/version.rb
42
+ - spec/fusuma/plugin/plugin/executors/wmctrl_executor_spec.rb
43
+ - spec/fusuma/plugin/wmctrl_spec.rb
44
+ - spec/helpers/config_helper.rb
45
+ - spec/spec_helper.rb
191
46
  homepage: https://github.com/iberianpig/fusuma-plugin-wmctrl
192
47
  licenses:
193
48
  - MIT
@@ -207,8 +62,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
207
62
  - !ruby/object:Gem::Version
208
63
  version: '0'
209
64
  requirements: []
210
- rubygems_version: 3.0.3
65
+ rubygems_version: 3.1.4
211
66
  signing_key:
212
67
  specification_version: 4
213
68
  summary: Wmctrl plugin for Fusuma
214
- test_files: []
69
+ test_files:
70
+ - spec/fusuma/plugin/plugin/executors/wmctrl_executor_spec.rb
71
+ - spec/fusuma/plugin/wmctrl_spec.rb
72
+ - spec/helpers/config_helper.rb
73
+ - spec/spec_helper.rb
data/.gitignore DELETED
@@ -1,12 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
-
11
- # rspec failure tracking
12
- .rspec_status
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/.rubocop.yml DELETED
@@ -1,15 +0,0 @@
1
- inherit_from: .rubocop_todo.yml
2
-
3
- Metrics/ModuleLength:
4
- Exclude:
5
- - "**/*_spec.rb"
6
-
7
- Metrics/BlockLength:
8
- Exclude:
9
- - "**/*_spec.rb"
10
- - "fusuma-plugin-*.gemspec"
11
-
12
- Metrics/LineLength:
13
- Max: 100
14
- Exclude:
15
- - "fusuma-plugin-*.gemspec"
data/.rubocop_todo.yml DELETED
@@ -1,20 +0,0 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2020-01-02 00:51:24 +0900 using RuboCop version 0.75.1.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
8
-
9
- # Offense count: 1
10
- Metrics/AbcSize:
11
- Max: 17
12
-
13
- # Offense count: 1
14
- Metrics/CyclomaticComplexity:
15
- Max: 8
16
-
17
- # Offense count: 1
18
- # Configuration parameters: CountComments, ExcludedMethods.
19
- Metrics/MethodLength:
20
- Max: 17
data/.travis.yml DELETED
@@ -1,10 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.3.1
7
- - 2.4
8
- - 2.5
9
- - 2.6
10
- before_install: gem install bundler --no-document -v 2.0.1
data/CHANGELOG.md DELETED
@@ -1,21 +0,0 @@
1
- # Change Log
2
-
3
- ## [Unreleased](https://github.com/iberianpig/fusuma-plugin-wmctrl/tree/HEAD)
4
-
5
- [Full Changelog](https://github.com/iberianpig/fusuma-plugin-wmctrl/compare/v0.2.0...HEAD)
6
-
7
- **Implemented enhancements:**
8
-
9
- - Control active window \(Close / Minimize / Maximize\) [\#2](https://github.com/iberianpig/fusuma-plugin-wmctrl/issues/2)
10
-
11
- ## [v0.2.0](https://github.com/iberianpig/fusuma-plugin-wmctrl/tree/v0.2.0) (2019-11-07)
12
- [Full Changelog](https://github.com/iberianpig/fusuma-plugin-wmctrl/compare/v0.1.0...v0.2.0)
13
-
14
- **Implemented enhancements:**
15
-
16
- - Move active window to next/prev workspace [\#1](https://github.com/iberianpig/fusuma-plugin-wmctrl/issues/1)
17
-
18
- ## [v0.1.0](https://github.com/iberianpig/fusuma-plugin-wmctrl/tree/v0.1.0) (2019-10-12)
19
-
20
-
21
- \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
data/CODE_OF_CONDUCT.md DELETED
@@ -1,74 +0,0 @@
1
- # Contributor Covenant Code of Conduct
2
-
3
- ## Our Pledge
4
-
5
- In the interest of fostering an open and welcoming environment, we as
6
- contributors and maintainers pledge to making participation in our project and
7
- our community a harassment-free experience for everyone, regardless of age, body
8
- size, disability, ethnicity, gender identity and expression, level of experience,
9
- nationality, personal appearance, race, religion, or sexual identity and
10
- orientation.
11
-
12
- ## Our Standards
13
-
14
- Examples of behavior that contributes to creating a positive environment
15
- include:
16
-
17
- * Using welcoming and inclusive language
18
- * Being respectful of differing viewpoints and experiences
19
- * Gracefully accepting constructive criticism
20
- * Focusing on what is best for the community
21
- * Showing empathy towards other community members
22
-
23
- Examples of unacceptable behavior by participants include:
24
-
25
- * The use of sexualized language or imagery and unwelcome sexual attention or
26
- advances
27
- * Trolling, insulting/derogatory comments, and personal or political attacks
28
- * Public or private harassment
29
- * Publishing others' private information, such as a physical or electronic
30
- address, without explicit permission
31
- * Other conduct which could reasonably be considered inappropriate in a
32
- professional setting
33
-
34
- ## Our Responsibilities
35
-
36
- Project maintainers are responsible for clarifying the standards of acceptable
37
- behavior and are expected to take appropriate and fair corrective action in
38
- response to any instances of unacceptable behavior.
39
-
40
- Project maintainers have the right and responsibility to remove, edit, or
41
- reject comments, commits, code, wiki edits, issues, and other contributions
42
- that are not aligned to this Code of Conduct, or to ban temporarily or
43
- permanently any contributor for other behaviors that they deem inappropriate,
44
- threatening, offensive, or harmful.
45
-
46
- ## Scope
47
-
48
- This Code of Conduct applies both within project spaces and in public spaces
49
- when an individual is representing the project or its community. Examples of
50
- representing a project or community include using an official project e-mail
51
- address, posting via an official social media account, or acting as an appointed
52
- representative at an online or offline event. Representation of a project may be
53
- further defined and clarified by project maintainers.
54
-
55
- ## Enforcement
56
-
57
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at yhkyky@gmail.com. All
59
- complaints will be reviewed and investigated and will result in a response that
60
- is deemed necessary and appropriate to the circumstances. The project team is
61
- obligated to maintain confidentiality with regard to the reporter of an incident.
62
- Further details of specific enforcement policies may be posted separately.
63
-
64
- Project maintainers who do not follow or enforce the Code of Conduct in good
65
- faith may face temporary or permanent repercussions as determined by other
66
- members of the project's leadership.
67
-
68
- ## Attribution
69
-
70
- This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at [http://contributor-covenant.org/version/1/4][version]
72
-
73
- [homepage]: http://contributor-covenant.org
74
- [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile DELETED
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- # Specify your gem's dependencies in fusuma-plugin-wmctrl.gemspec
6
- gemspec
data/Rakefile DELETED
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- task default: :spec
9
-
10
- require 'github_changelog_generator/task'
11
-
12
- GitHubChangelogGenerator::RakeTask.new :changelog do |config|
13
- config.user = 'iberianpig'
14
- config.project = 'fusuma-plugin-wmctrl'
15
- end