swm 0.2.0 → 0.3.0

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
  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