swm 0.0.2 → 0.1.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 +4 -4
- data/.rspec +2 -0
- data/CHANGELOG.md +3 -0
- data/Guardfile +6 -0
- data/README.md +41 -1
- data/bin/swm +57 -1
- data/lib/swm.rb +5 -4
- data/lib/swm/command_runner.rb +13 -0
- data/lib/swm/commands/move_command.rb +51 -0
- data/lib/swm/screen.rb +7 -0
- data/lib/swm/version.rb +1 -1
- data/lib/swm/window.rb +72 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/unit/window_spec.rb +26 -0
- data/swm.gemspec +4 -0
- metadata +56 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b9b935a723ff0b91c3e27f18b2d54153d691b57
|
4
|
+
data.tar.gz: 101329a7748b14884ffd2a1dbc6a821a2f272eff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f425c6c926ff11f6a083d291df1b374573eb14343de122372b5f978db72769ed7d60b083e59c9f43a42868d21b5b9066db15b0f6917d292e01e52fe7cd015915
|
7
|
+
data.tar.gz: 85471aa02e014ae4fa1f5d8e6fdfdc1d04d1e6174558daeca1761caf0280da215012f693eafda7b464639873cbcb575c65808f51b27a752350bea4f50b5ef151
|
data/.rspec
ADDED
data/CHANGELOG.md
ADDED
data/Guardfile
ADDED
data/README.md
CHANGED
@@ -8,9 +8,49 @@ SWM is a utility to place and resize windows, written for Ubuntu. It might work
|
|
8
8
|
|
9
9
|
$ gem install swm
|
10
10
|
|
11
|
+
## Dependencies
|
12
|
+
|
13
|
+
Some command line tools are needed:
|
14
|
+
|
15
|
+
- xdotool (for getting window id if current window)
|
16
|
+
- wmctrl (for moving and reizing windows)
|
17
|
+
- xdpyinfo (for getting screen dimensions)
|
18
|
+
- xwininfo (for getting window information)
|
19
|
+
|
20
|
+
Install these with apt-get if they are not on your system.
|
21
|
+
|
11
22
|
## Usage
|
12
23
|
|
13
|
-
|
24
|
+
### Moving windows
|
25
|
+
|
26
|
+
Move windows with the move subcommand.
|
27
|
+
It accepts parameters x and y which can both be specified in percentages of free screen space.
|
28
|
+
|
29
|
+
Examples:
|
30
|
+
|
31
|
+
swm move --x 50% --y 50%
|
32
|
+
|
33
|
+
Will center the window
|
34
|
+
|
35
|
+
swm move --x 0%
|
36
|
+
|
37
|
+
Will move the window to the left edge of the sceen, preserving the Y position
|
38
|
+
|
39
|
+
There are some predefined constants that can be used to specify position:
|
40
|
+
|
41
|
+
- For X these are: left, middle and right.
|
42
|
+
- For Y is is: top, middle, bottom
|
43
|
+
|
44
|
+
For example:
|
45
|
+
|
46
|
+
swm move --x right --y middle
|
47
|
+
|
48
|
+
Will move the window to the middle of the right edge.
|
49
|
+
|
50
|
+
|
51
|
+
### Resizing windows
|
52
|
+
|
53
|
+
Not yet supported
|
14
54
|
|
15
55
|
## Contributing
|
16
56
|
|
data/bin/swm
CHANGED
@@ -1,5 +1,61 @@
|
|
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)
|
5
|
+
|
6
|
+
require 'trollop'
|
3
7
|
require 'swm'
|
4
8
|
|
5
|
-
|
9
|
+
def run
|
10
|
+
options = get_options
|
11
|
+
begin
|
12
|
+
Swm::CommandRunner.run options[:command], options[:command_options], options[:global_options]
|
13
|
+
rescue Exception => ex
|
14
|
+
puts ex.message
|
15
|
+
exit(1)
|
16
|
+
end
|
17
|
+
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 :width, "The width in pixels", type: Integer
|
57
|
+
opt :height, "The height in pixels", type: Integer
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
run
|
data/lib/swm.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
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/move_command"
|
@@ -0,0 +1,13 @@
|
|
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
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Swm
|
2
|
+
class MoveCommand
|
3
|
+
def initialize(command_options = {}, global_options = {})
|
4
|
+
@command_options = command_options
|
5
|
+
@global_options = global_options
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
window = Swm::Window.current
|
10
|
+
|
11
|
+
x_percentage = get_x_percentage
|
12
|
+
y_percentage = get_y_percentage
|
13
|
+
|
14
|
+
screen_dimensions = Screen.dimensions
|
15
|
+
|
16
|
+
x = y = nil
|
17
|
+
x = ((screen_dimensions[0] - window.width) * x_percentage / 100.0).to_i if x_percentage
|
18
|
+
y = ((screen_dimensions[1] - window.height) * y_percentage / 100.0).to_i if y_percentage
|
19
|
+
|
20
|
+
window.move x, y
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_x_percentage
|
24
|
+
get_placement_percentage :x, {
|
25
|
+
left: 0,
|
26
|
+
middle: 50,
|
27
|
+
right: 100
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_y_percentage
|
32
|
+
get_placement_percentage :y, {
|
33
|
+
top: 0,
|
34
|
+
middle: 50,
|
35
|
+
bottom: 100
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_placement_percentage(axis, constants)
|
40
|
+
raw_value = @command_options[axis]
|
41
|
+
return nil if raw_value.nil?
|
42
|
+
if value = constants[raw_value.to_sym]
|
43
|
+
value
|
44
|
+
elsif /(\d+(\.\d+)?)\%/ =~ raw_value
|
45
|
+
$1.to_f
|
46
|
+
else
|
47
|
+
raise "Unknown placement option: #{raw_value}. Valid options are percentages (e.g. 30%) and [#{constants.map{|x| x.first.to_s}.join(' ')}]"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/swm/screen.rb
ADDED
data/lib/swm/version.rb
CHANGED
data/lib/swm/window.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
module Swm
|
2
|
+
class Window
|
3
|
+
def self.current
|
4
|
+
Window.new `xdotool getwindowfocus`.to_i
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(id)
|
8
|
+
@id = id
|
9
|
+
end
|
10
|
+
|
11
|
+
def width
|
12
|
+
xwininfo_integer_property "Width"
|
13
|
+
end
|
14
|
+
|
15
|
+
def height
|
16
|
+
xwininfo_integer_property "Height"
|
17
|
+
end
|
18
|
+
|
19
|
+
def pos_x
|
20
|
+
xwininfo_integer_property "Absolute upper-left X"
|
21
|
+
end
|
22
|
+
|
23
|
+
def pos_y
|
24
|
+
xwininfo_integer_property "Absolute upper-left Y"
|
25
|
+
end
|
26
|
+
|
27
|
+
def move(x, y)
|
28
|
+
x ||= pos_x
|
29
|
+
y ||= pos_y
|
30
|
+
command = "wmctrl -i -r #{@id} -e 0,#{x},#{y},#{width},#{height}"
|
31
|
+
exec command
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
##
|
37
|
+
# xwininfo will tell stuff about the requested window
|
38
|
+
#
|
39
|
+
# Sample output:
|
40
|
+
#
|
41
|
+
# xwininfo: Window id: 0x3c00862 "xwininfo -id 62916706"
|
42
|
+
#
|
43
|
+
# Absolute upper-left X: 1
|
44
|
+
# Absolute upper-left Y: 52
|
45
|
+
# Relative upper-left X: 0
|
46
|
+
# Relative upper-left Y: 0
|
47
|
+
# Width: 992
|
48
|
+
# Height: 596
|
49
|
+
# Depth: 32
|
50
|
+
# Visual: 0x6c
|
51
|
+
# Visual Class: TrueColor
|
52
|
+
# Border width: 0
|
53
|
+
# Class: InputOutput
|
54
|
+
# Colormap: 0x3c00005 (not installed)
|
55
|
+
# Bit Gravity State: NorthWestGravity
|
56
|
+
# Window Gravity State: NorthWestGravity
|
57
|
+
# Backing Store State: NotUseful
|
58
|
+
# Save Under State: no
|
59
|
+
# Map State: IsViewable
|
60
|
+
# Override Redirect State: no
|
61
|
+
# Corners: +1+52 -927+52 -927-432 +1-432
|
62
|
+
# -geometry 110x33+-7+24
|
63
|
+
#
|
64
|
+
def xwininfo
|
65
|
+
@xwininfo ||= `xwininfo -id #{@id}`
|
66
|
+
end
|
67
|
+
|
68
|
+
def xwininfo_integer_property(name)
|
69
|
+
/#{name}: +(\d+)/.match(xwininfo)[1].to_i
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
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
|
+
require 'swm'
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
12
|
+
config.run_all_when_everything_filtered = true
|
13
|
+
config.filter_run :focus
|
14
|
+
|
15
|
+
# Run specs in random order to surface order dependencies. If you find an
|
16
|
+
# order dependency and want to debug it, you can fix the order by providing
|
17
|
+
# the seed, which is printed after each run.
|
18
|
+
# --seed 1234
|
19
|
+
config.order = 'random'
|
20
|
+
end
|
21
|
+
RSpec.configure do |config|
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Swm::Window do
|
4
|
+
|
5
|
+
let(:window) { Swm::Window.current }
|
6
|
+
|
7
|
+
describe 'height' do
|
8
|
+
subject { window.height }
|
9
|
+
it { should be_kind_of Integer }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'width' do
|
13
|
+
subject { window.width }
|
14
|
+
it { should be_kind_of Integer }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'pos_x' do
|
18
|
+
subject { window.pos_x }
|
19
|
+
it { should be_kind_of Integer }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'pos_y' do
|
23
|
+
subject { window.pos_y }
|
24
|
+
it { should be_kind_of Integer }
|
25
|
+
end
|
26
|
+
end
|
data/swm.gemspec
CHANGED
@@ -24,6 +24,10 @@ 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
|
+
|
27
29
|
spec.add_development_dependency "bundler", "~> 1.3"
|
28
30
|
spec.add_development_dependency "rake"
|
31
|
+
spec.add_development_dependency "rspec"
|
32
|
+
spec.add_development_dependency "guard-rspec"
|
29
33
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.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-06-
|
11
|
+
date: 2013-06-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'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +52,34 @@ dependencies:
|
|
38
52
|
- - '>='
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: guard-rspec
|
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'
|
41
83
|
description: "\n Simple Window Manager is a utillity to move and place windows
|
42
84
|
in Ubuntu.\n It might work with other *nix distributions.\n\n The utillity
|
43
85
|
is intended to be used with keyboard shortcuts, and is\n always operating on
|
@@ -50,13 +92,22 @@ extensions: []
|
|
50
92
|
extra_rdoc_files: []
|
51
93
|
files:
|
52
94
|
- .gitignore
|
95
|
+
- .rspec
|
96
|
+
- CHANGELOG.md
|
53
97
|
- Gemfile
|
98
|
+
- Guardfile
|
54
99
|
- LICENSE.txt
|
55
100
|
- README.md
|
56
101
|
- Rakefile
|
57
102
|
- bin/swm
|
58
103
|
- lib/swm.rb
|
104
|
+
- lib/swm/command_runner.rb
|
105
|
+
- lib/swm/commands/move_command.rb
|
106
|
+
- lib/swm/screen.rb
|
59
107
|
- lib/swm/version.rb
|
108
|
+
- lib/swm/window.rb
|
109
|
+
- spec/spec_helper.rb
|
110
|
+
- spec/unit/window_spec.rb
|
60
111
|
- swm.gemspec
|
61
112
|
homepage: https://github.com/lasseebert/swm
|
62
113
|
licenses:
|
@@ -82,4 +133,6 @@ rubygems_version: 2.0.2
|
|
82
133
|
signing_key:
|
83
134
|
specification_version: 4
|
84
135
|
summary: Simple Window Manager for Ubuntu
|
85
|
-
test_files:
|
136
|
+
test_files:
|
137
|
+
- spec/spec_helper.rb
|
138
|
+
- spec/unit/window_spec.rb
|