swm 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6737404f8274bcc90d25baabc3dea109decebb3a
4
- data.tar.gz: 46d9434f2c901bedb01808f0d49ac7afe55159e8
3
+ metadata.gz: 7f50f3f5177da5b45f1a978104282c731c938c7b
4
+ data.tar.gz: d001853d778a5e530564ab8a589f8aa509e088b9
5
5
  SHA512:
6
- metadata.gz: 7c7792e75db029104688077385a794685967b49f7ec429f94a1cdecad1c8d6432a90906a7f477956b75cb9c051aced4bc0552a17f5555c9296640226aefc466d
7
- data.tar.gz: e6ada0b85afd5c74868ee306ffe5ba503c6f8e89185f334b113afb936f94bc2a672cc4f93dbb6db574b879e6ab2823d15774d69bc3f0c89f33fc0d57310f6ba3
6
+ metadata.gz: 5c09872afc8b12946708965ee9db6ea14ccb34b21925db6895c7037a6d375f38cc0c33174172e8b4b37ae0e5238a3a6c6fe8f455b5f0234dc51c6a56382aab5f
7
+ data.tar.gz: 165d8d3393603336ad635b7d4191843e07ae696953125ea6467fab0d3921aa626ef779651268b4b8246fda72460eba6946dbdf4bcdf2d96f8938606f845f569d
data/.gitignore CHANGED
@@ -15,3 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+
19
+ sandi_meter
@@ -1,3 +1,17 @@
1
+ ## Version 0.3.0 (current)
2
+
3
+ This version contains breaking changes - still alpha-like
4
+
5
+ - New simple option parser instead of trollop
6
+ - Simpler bin file
7
+ - Simpler architecture
8
+ - Resize command rewritten, now has new args
9
+ - Move command rewritten and has new args
10
+
11
+ ## Version 0.2.0
12
+
13
+ - Resize is supported with the `resize` command
14
+
1
15
  ## Version 0.1.0
2
16
 
3
17
  - Moving windows is now supported with the `move` subcommand
data/Guardfile CHANGED
@@ -1,4 +1,4 @@
1
- guard :rspec do
1
+ guard :rspec, cmd: "bundle exec rspec -f documentation" do
2
2
  watch(%r{^spec/.+_spec\.rb$})
3
3
  watch(%r{^lib/(.+)\.rb$}) { "spec" }
4
4
  watch(%w[ spec/spec_helper.rb Gemfile.lock ]) { "spec" }
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Dependency Status](https://gemnasium.com/lasseebert/swm.png)](https://gemnasium.com/lasseebert/swm)
2
+
1
3
  # Simple Window Manager
2
4
 
3
5
  SWM is a utility to place and resize windows, written for Ubuntu. It might work with other *nix distributions.
@@ -32,33 +34,29 @@ It accepts parameters `x` and `y` which can both be specified in percentages of
32
34
 
33
35
  Examples:
34
36
 
35
- swm move --x 50% --y 50%
37
+ swm move --x 50 --y 50
36
38
 
37
39
  Will center the window
38
40
 
39
- swm move --x 0%
40
-
41
- Will move the window to the left edge of the sceen, preserving the Y position
42
-
43
- There are some predefined constants that can be used to specify position:
41
+ swm move --x 0 --y 100
44
42
 
45
- - For X these are: `left`, `middle` and `right`.
46
- - For Y it is: `top`, `middle`, `bottom`.
43
+ Will move the window to the top right corner
47
44
 
48
- For example:
45
+ ### Resizing windows
49
46
 
50
- swm move --x right --y middle
47
+ Resize windows with the `resize` command
48
+ It accepts `x`, `y`, `width` and `height`.
51
49
 
52
- Will move the window to the middle of the right edge.
50
+ Example:
53
51
 
52
+ swm resize --x 10 --y 10 --width 80 --height 80
54
53
 
55
- ### Resizing windows
54
+ Will resize and move the window so that it has 10% of the screen size to all screen edges.
56
55
 
57
- Not yet supported
58
56
 
59
57
  ## Contributing
60
58
 
61
- 1. Fork it
59
+ 1. Fork 8t
62
60
  2. Create your feature branch (`git checkout -b my-new-feature`)
63
61
  3. Commit your changes (`git commit -am 'Add some feature'`)
64
62
  4. Push to the branch (`git push origin my-new-feature`)
data/bin/swm CHANGED
@@ -1,63 +1,23 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- lib = File.expand_path('../../lib', __FILE__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require_relative '../lib/swm'
5
4
 
6
- require 'trollop'
7
- require 'swm'
5
+ command_name = ARGV.shift
6
+ command = Swm::Command.registered_commands[command_name]
8
7
 
9
- def run
10
- options = get_options
8
+ if command
11
9
  begin
12
- Swm::CommandRunner.run options[:command], options[:command_options], options[:global_options]
13
- rescue Exception => ex
14
- puts ex.message
15
- exit(1)
10
+ options = Swm::CliOptions.new(ARGV)
11
+ command.run(options)
12
+ rescue => e
13
+ puts e
14
+ command.print_help
16
15
  end
16
+ else
17
+ puts <<-EOF
18
+ Usage: swm <command> <options>
19
+ Commands:
20
+ resize
21
+ move
22
+ EOF
17
23
  end
18
-
19
- def get_options
20
- global_options = Trollop::options do
21
- banner "utility that can move and resize windows"
22
- stop_on %w[ move resize ]
23
- end
24
- { global_options: global_options }.merge get_command
25
- end
26
-
27
- def get_command
28
- command = ARGV.shift
29
- Trollop.die "no command" unless command
30
- command = command.to_sym
31
- { command: command }.merge get_command_options(command)
32
- end
33
-
34
- def get_command_options(command)
35
- {
36
- command_options: case command
37
- when :move
38
- get_move_options
39
- when :resize
40
- get_resize_options
41
- else
42
- Trollop::die "unknown command #{command.to_s}"
43
- end
44
- }
45
- end
46
-
47
- def get_move_options
48
- Trollop::options do
49
- opt :x, "The placement on the x-axis: left, middle, right, or 0%-100%", type: String
50
- opt :y, "The placement on the y-axis: top, middle, bottom, or 0%-100%", type: String
51
- end
52
- end
53
-
54
- def get_resize_options
55
- Trollop::options do
56
- opt :x1, "The placement of the left edge: left, middle, right, or 0%-100%", type: String
57
- opt :x2, "The placement of the right edge: left, middle, right, or 0%-100%", type: String
58
- opt :y1, "The placement of the top edge: top, middle, bottom, or 0%-100%", type: String
59
- opt :y2, "The placement of the bottom edge: top, middle, bottom, or 0%-100%", type: String
60
- end
61
- end
62
-
63
- run
data/lib/swm.rb CHANGED
@@ -1,7 +1,3 @@
1
- require_relative "swm/version"
2
- require_relative "swm/window"
3
- require_relative "swm/screen"
4
- require_relative "swm/command_runner"
5
- require_relative "swm/commands/command"
6
- require_relative "swm/commands/resize_command"
7
- require_relative "swm/commands/move_command"
1
+ Dir["#{File.dirname(__FILE__)}/swm/**/*.rb"].each do |file|
2
+ require file
3
+ end
@@ -0,0 +1,33 @@
1
+ module Swm
2
+ class CliOptions < Hash
3
+
4
+ def initialize(args)
5
+ merge!(parse_options(args))
6
+ end
7
+
8
+ private
9
+
10
+ def parse_options(args)
11
+ pairs = args.each_slice(2)
12
+ pairs = pairs.map { |pair| parse_pair(pair) }
13
+ Hash[pairs]
14
+ end
15
+
16
+ def parse_pair(pair)
17
+ raise "Misplaced option value: #{pair[0]}" unless pair[0].start_with?('--')
18
+ raise "No option value for #{pair[0]}" if pair.length == 1
19
+ raise "Misplaced option key: #{pair[1]}" if pair[1].start_with?('--')
20
+ [pair[0].sub(/^--/, '').to_sym, decode_value(pair[1])]
21
+ end
22
+
23
+ def decode_value(arg)
24
+ if arg =~ /\d+/
25
+ arg.to_i
26
+ else
27
+ arg
28
+ end
29
+ end
30
+
31
+
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ module Swm
2
+ class Command
3
+ def self.register(name, klass)
4
+ registered_commands[name] = klass
5
+ end
6
+
7
+ def self.registered_commands
8
+ @registered_commands ||= {}
9
+ end
10
+ end
11
+ end
@@ -1,17 +1,42 @@
1
1
  module Swm
2
- class MoveCommand < Command
2
+ class MoveCommand
3
3
 
4
- def run
5
- window = Swm::Window.current
4
+ Command.register("move", self)
5
+
6
+ def self.run(options)
7
+ new(options).run
8
+ end
9
+
10
+ def self.print_help
11
+ puts <<-EOF
12
+ Usage: swm move <options>
13
+ Options:
14
+ --x: Percentage of free screen width
15
+ --y: Percentage of free screen height
16
+ Examples:
17
+ Center the window
18
+ swm resize --x 50 --y 50
19
+ Move the window to the top-right corner
20
+ swm resize --x 100 --y 0
21
+
22
+ EOF
23
+ end
24
+
25
+ attr_reader :options
26
+
27
+ def initialize(options)
28
+ @options = options
29
+ end
6
30
 
7
- x_percentage = get_x_percentage
8
- y_percentage = get_y_percentage
31
+ def run
32
+ x_percent = options[:x]
33
+ y_percent = options[:y]
9
34
 
10
35
  screen_dimensions = Screen.dimensions
36
+ window = Swm::Window.current
11
37
 
12
- x = y = nil
13
- x = ((screen_dimensions[0] - window.width) * x_percentage / 100.0).to_i if x_percentage
14
- y = ((screen_dimensions[1] - window.height) * y_percentage / 100.0).to_i if y_percentage
38
+ x = ((screen_dimensions[0] - window.width) * x_percent / 100.0).to_i
39
+ y = ((screen_dimensions[1] - window.height) * y_percent / 100.0).to_i
15
40
 
16
41
  window.move x, y
17
42
  end
@@ -1,26 +1,66 @@
1
1
  module Swm
2
- class ResizeCommand < Command
2
+ class ResizeCommand
3
3
 
4
- def run
5
- x1 = get_x_percentage :x1
6
- x2 = get_x_percentage :x2
7
- y1 = get_y_percentage :y1
8
- y2 = get_y_percentage :y2
4
+ Command.register("resize", self)
5
+
6
+ def self.run(options)
7
+ new(options).run
8
+ end
9
9
 
10
+ def self.print_help
11
+ puts <<-EOF
12
+ Usage: swm resize <options>
13
+ Options:
14
+ --x: X-coord of top-left corner in percent of screen
15
+ --y: Y-ccord of top-left corner in percent of screen
16
+ --width: Width in percent of screen
17
+ --height: Height in percent of screen
18
+ --left: (Optional) Sets a left margin of the screen
19
+ --right: (Optional) Sets a right margin of the screen
20
+ --top: (Optional) Sets a top margin of the screen
21
+ --bottom: (Optional) Sets a bottom margin of the screen
22
+ Examples:
23
+ Make window fill 80 percent of screen in each dimension with a 10 percent margin:
24
+ swm resize --x 10 --y 10 --width 80 --height 80
25
+ EOF
26
+ end
27
+
28
+ attr_reader :options
29
+
30
+ def initialize(options)
31
+ @options = options
32
+ end
33
+
34
+ def run
10
35
  screen_dimensions = Screen.dimensions
11
- window = Swm::Window.current
36
+ rect = [0, 0, screen_dimensions[0], screen_dimensions[1]]
37
+ set_offset(rect)
38
+ resize_in_rect(rect)
39
+ end
40
+
41
+ private
42
+
43
+ def set_offset(rect)
44
+ rect[0] += options[:left] || 0
45
+ rect[2] -= options[:left] || 0
46
+ rect[1] += options[:top] || 0
47
+ rect[3] -= options[:top] || 0
48
+ rect[2] -= options[:right] || 0
49
+ rect[3] -= options[:bottom] || 0
50
+ end
12
51
 
13
- x = y = width = height = nil
14
- x = (screen_dimensions[0] * x1 / 100.0).to_i if x1
15
- y = (screen_dimensions[1] * y1 / 100.0).to_i if y1
16
- width = (screen_dimensions[0] * x2 / 100.0).to_i - (x || window.pos_x) if x2
17
- height = (screen_dimensions[1] * y2 / 100.0).to_i - (y || window.pos_y) if y2
52
+ def resize_in_rect(rect)
53
+ x_percent = options[:x]
54
+ y_percent = options[:y]
55
+ width_percent = options[:width]
56
+ height_percent = options[:height]
18
57
 
19
- puts "x: #{x}"
20
- puts "y: #{y}"
21
- puts "width: #{width}"
22
- puts "height: #{height}"
58
+ x = (rect[0] + rect[2] * x_percent / 100.0).to_i
59
+ y = (rect[1] + rect[3] * y_percent / 100.0).to_i
60
+ width = (rect[2] * width_percent / 100.0).to_i
61
+ height = (rect[3] * height_percent / 100.0).to_i
23
62
 
63
+ window = Window.current
24
64
  window.set x, y, width, height
25
65
  end
26
66
 
@@ -1,3 +1,3 @@
1
1
  module Swm
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -1,5 +1,8 @@
1
1
  module Swm
2
2
  class Window
3
+
4
+ attr_reader :id
5
+
3
6
  def self.current
4
7
  Window.new `xdotool getwindowfocus`.to_i
5
8
  end
@@ -27,7 +30,7 @@ module Swm
27
30
  def move(x, y)
28
31
  x ||= pos_x
29
32
  y ||= pos_y
30
- set x, y, nil, nil
33
+ set x, y, width, height
31
34
  end
32
35
 
33
36
  def set(x, y, w, h)
@@ -36,7 +39,8 @@ module Swm
36
39
  w ||= width
37
40
  h ||= height
38
41
  command = "wmctrl -i -r #{@id} -e 0,#{x},#{y},#{w},#{h}"
39
- exec command
42
+ system command
43
+ raise "Error running #{command}" unless $?.success?
40
44
  clear_cache
41
45
  end
42
46
 
@@ -1,10 +1,3 @@
1
- # This file was generated by the `rspec --init` command. Conventionally, all
2
- # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
- # Require this file using `require "spec_helper"` to ensure that it is only
4
- # loaded once.
5
- #
6
- # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
-
8
1
  require 'swm'
9
2
 
10
3
  RSpec.configure do |config|
@@ -18,5 +11,3 @@ RSpec.configure do |config|
18
11
  # --seed 1234
19
12
  config.order = 'random'
20
13
  end
21
- RSpec.configure do |config|
22
- end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Swm::CliOptions do
4
+ describe '#initialize' do
5
+ it "should parse empty array" do
6
+ options = Swm::CliOptions.new([])
7
+ expect(options.size).to be_zero
8
+ end
9
+
10
+ it "should parse one named option" do
11
+ options = Swm::CliOptions.new(["--foo", "bar"])
12
+ expect(options.size).to eq(1)
13
+ expect(options[:foo]).to eq("bar")
14
+ end
15
+
16
+ it "should parse one named option with integer value" do
17
+ options = Swm::CliOptions.new(["--foo", "42"])
18
+ expect(options.size).to eq(1)
19
+ expect(options[:foo]).to eq(42)
20
+ end
21
+
22
+ it "should parse multiple named options" do
23
+ options = Swm::CliOptions.new(["--foo", "42", "--bar", "baz"])
24
+ expect(options.size).to eq(2)
25
+ expect(options[:foo]).to eq(42)
26
+ expect(options[:bar]).to eq("baz")
27
+ end
28
+
29
+ it "should complain about invalid options" do
30
+ invalid_inputs = [
31
+ ["--foo"],
32
+ ["--foo", "--bar"],
33
+ ["--foo", "42", "--bar"],
34
+ ["42", "--foo"]
35
+ ]
36
+ invalid_inputs.each do |input|
37
+ expect { Swm::CliOptions.new(input) }.to raise_error
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Swm::ResizeCommand do
4
+ end
@@ -24,8 +24,6 @@ Gem::Specification.new do |spec|
24
24
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
25
25
  spec.require_paths = ["lib"]
26
26
 
27
- spec.add_dependency "trollop"
28
-
29
27
  spec.add_development_dependency "bundler", "~> 1.3"
30
28
  spec.add_development_dependency "rake"
31
29
  spec.add_development_dependency "rspec"
metadata CHANGED
@@ -1,83 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lasse Skindstad Ebert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-26 00:00:00.000000000 Z
11
+ date: 2014-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: trollop
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - '>='
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - '>='
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: bundler
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
- - - ~>
17
+ - - "~>"
32
18
  - !ruby/object:Gem::Version
33
19
  version: '1.3'
34
20
  type: :development
35
21
  prerelease: false
36
22
  version_requirements: !ruby/object:Gem::Requirement
37
23
  requirements:
38
- - - ~>
24
+ - - "~>"
39
25
  - !ruby/object:Gem::Version
40
26
  version: '1.3'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: rake
43
29
  requirement: !ruby/object:Gem::Requirement
44
30
  requirements:
45
- - - '>='
31
+ - - ">="
46
32
  - !ruby/object:Gem::Version
47
33
  version: '0'
48
34
  type: :development
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
- - - '>='
38
+ - - ">="
53
39
  - !ruby/object:Gem::Version
54
40
  version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: rspec
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
- - - '>='
45
+ - - ">="
60
46
  - !ruby/object:Gem::Version
61
47
  version: '0'
62
48
  type: :development
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
- - - '>='
52
+ - - ">="
67
53
  - !ruby/object:Gem::Version
68
54
  version: '0'
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: guard-rspec
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
- - - '>='
59
+ - - ">="
74
60
  - !ruby/object:Gem::Version
75
61
  version: '0'
76
62
  type: :development
77
63
  prerelease: false
78
64
  version_requirements: !ruby/object:Gem::Requirement
79
65
  requirements:
80
- - - '>='
66
+ - - ">="
81
67
  - !ruby/object:Gem::Version
82
68
  version: '0'
83
69
  description: "\n Simple Window Manager is a utillity to move and place windows
@@ -91,8 +77,8 @@ executables:
91
77
  extensions: []
92
78
  extra_rdoc_files: []
93
79
  files:
94
- - .gitignore
95
- - .rspec
80
+ - ".gitignore"
81
+ - ".rspec"
96
82
  - CHANGELOG.md
97
83
  - Gemfile
98
84
  - Guardfile
@@ -101,14 +87,16 @@ files:
101
87
  - Rakefile
102
88
  - bin/swm
103
89
  - lib/swm.rb
104
- - lib/swm/command_runner.rb
105
- - lib/swm/commands/command.rb
90
+ - lib/swm/cli_options.rb
91
+ - lib/swm/command.rb
106
92
  - lib/swm/commands/move_command.rb
107
93
  - lib/swm/commands/resize_command.rb
108
94
  - lib/swm/screen.rb
109
95
  - lib/swm/version.rb
110
96
  - lib/swm/window.rb
111
97
  - spec/spec_helper.rb
98
+ - spec/unit/cli_options_spec.rb
99
+ - spec/unit/commands/resize_command_spec.rb
112
100
  - spec/unit/window_spec.rb
113
101
  - swm.gemspec
114
102
  homepage: https://github.com/lasseebert/swm
@@ -121,20 +109,22 @@ require_paths:
121
109
  - lib
122
110
  required_ruby_version: !ruby/object:Gem::Requirement
123
111
  requirements:
124
- - - '>='
112
+ - - ">="
125
113
  - !ruby/object:Gem::Version
126
114
  version: '0'
127
115
  required_rubygems_version: !ruby/object:Gem::Requirement
128
116
  requirements:
129
- - - '>='
117
+ - - ">="
130
118
  - !ruby/object:Gem::Version
131
119
  version: '0'
132
120
  requirements: []
133
121
  rubyforge_project:
134
- rubygems_version: 2.0.3
122
+ rubygems_version: 2.2.0
135
123
  signing_key:
136
124
  specification_version: 4
137
125
  summary: Simple Window Manager for Ubuntu
138
126
  test_files:
139
127
  - spec/spec_helper.rb
128
+ - spec/unit/cli_options_spec.rb
129
+ - spec/unit/commands/resize_command_spec.rb
140
130
  - spec/unit/window_spec.rb
@@ -1,13 +0,0 @@
1
- module Swm
2
-
3
- class CommandRunner
4
- def self.run(command, command_options = {}, global_options = {})
5
- command = get_command_class(command).new command_options, global_options
6
- command.run
7
- end
8
-
9
- def self.get_command_class(command)
10
- Swm.const_get "#{command.capitalize}Command"
11
- end
12
- end
13
- end
@@ -1,40 +0,0 @@
1
- module Swm
2
- class Command
3
- def initialize(command_options = {}, global_options = {})
4
- @command_options = command_options
5
- @global_options = global_options
6
- end
7
-
8
- def run
9
- raise "Override in sub derived class"
10
- end
11
-
12
- def get_x_percentage(name = :x)
13
- get_placement_percentage name, {
14
- left: 0,
15
- middle: 50,
16
- right: 100
17
- }
18
- end
19
-
20
- def get_y_percentage(name = :y)
21
- get_placement_percentage name, {
22
- top: 0,
23
- middle: 50,
24
- bottom: 100
25
- }
26
- end
27
-
28
- def get_placement_percentage(name, constants)
29
- raw_value = @command_options[name]
30
- return nil if raw_value.nil?
31
- if value = constants[raw_value.to_sym]
32
- value
33
- elsif /(\d+(\.\d+)?)\%/ =~ raw_value
34
- $1.to_f
35
- else
36
- raise "Unknown placement option: #{raw_value}. Valid options are percentages (e.g. 30%) and [#{constants.map{|x| x.first.to_s}.join(' ')}]"
37
- end
38
- end
39
- end
40
- end