wmctile 0.1.0 → 0.1.1

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: 9474c678206339ee6e362df09689aef832d39fe3
4
- data.tar.gz: 6a044f9a0bf34619394dc6b34e3cece57b8ecfcf
3
+ metadata.gz: d4216479b45b21cb886179229cc5575b55b3fe1f
4
+ data.tar.gz: fb6b1145637252d54ba0620ed27ee10bc94dd206
5
5
  SHA512:
6
- metadata.gz: 2ed77ce751f458f2fbca1de12acfaf3a4042c85a5bf548c7030ba95c925f13a6daa072c54a5b039c5d3df8a208110530063e99154f371a7553fb8baa80231499
7
- data.tar.gz: 72909e8e7b1fb0ad795f6fd77b4e2f92c8631b51031138d675319f976df95561d7ae3bc571c6af35eda59474d6dfa43f2c36e991835479cd425afe3c1828bfa6
6
+ metadata.gz: 58ecfd20728f51d591d0b13d241046acae6bf1047ec37b9feb9158ae9275299a6506cfb1b76d9e6785d5be361a43328caed81a31e1eee8b6d6596048c4f77691
7
+ data.tar.gz: 5d981b8f5400b7fb1762e69797d33e764135a6052074db3073c96e7acd12626fa7ecfb988152a13ed0e8e5ce0959c85c9568fdb5d3cda9b5be98e047c19d0009
data/bin/wmctile ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/wmctile'
3
+
4
+ router = Wmctile::Router.new
5
+ router.dispatch ARGV
@@ -0,0 +1,13 @@
1
+ class Wmctile::Class
2
+ def cmd cmd
3
+ # [0..-2] to strip the last \n
4
+ `#{ cmd }`[0..-2]
5
+ end
6
+ def notify title, string, icon = nil
7
+ if icon
8
+ system "notify-send -i '#{ icon }' '#{title}' '#{string}'"
9
+ else
10
+ system "notify-send '#{title}' '#{string}'"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ require 'dmenu'
2
+
3
+ class Wmctile::ClassWithDmenu < Wmctile::Class
4
+ def dmenu items
5
+ a = Dmenu.new
6
+ # override defaults
7
+ a.background = '#242424'
8
+ a.case_insensitive = true
9
+ a.font = 'Ubuntu Mono-12'
10
+ a.foreground = 'white'
11
+ a.lines = 10
12
+ a.position = :bottom
13
+ a.selected_background = '#2e557e'
14
+ # set items
15
+ a.items = items
16
+ # run
17
+ b = a.run()
18
+ if b.is_a? Dmenu::Item
19
+ return b.value
20
+ else
21
+ return b
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,64 @@
1
+ require 'yaml'
2
+
3
+ class Wmctile::Memory < Wmctile::Class
4
+ ##################################
5
+ ## init ##########################
6
+ ##################################
7
+ def initialize
8
+ @path = File.expand_path '~/.config/wmctile/wmctile-memory.yml'
9
+ if not File.exist? @path
10
+ raw_memory = self.create_new_memory
11
+ end
12
+ raw_memory ||= File.read @path
13
+ @memory = YAML.load(raw_memory)
14
+ end
15
+ def create_new_memory
16
+ dir_path = @path[/(.*)\/wmctile-memory.yml/, 1]
17
+ if not Dir.exists? dir_path
18
+ Dir.mkdir dir_path
19
+ end
20
+ out_file = File.new @path, 'w'
21
+ # 20 workspaces should suffice
22
+ 20.times do |i|
23
+ out_file.puts "#{i}:"
24
+ end
25
+ out_file.close
26
+ end
27
+ def write_memory
28
+ out_file = File.new @path, 'w'
29
+ out_file.puts @memory.to_yaml
30
+ out_file.close
31
+ end
32
+ ##################################
33
+ ## getters/setters ###############
34
+ ##################################
35
+ def get workspace = 0, key = nil, key_sub = nil
36
+ begin
37
+ a = @memory[workspace]
38
+ if key.nil?
39
+ return nil
40
+ else
41
+ a = a[key]
42
+ if key_sub.nil?
43
+ return a
44
+ else
45
+ return a[key_sub]
46
+ end
47
+ end
48
+ rescue Exception => e
49
+ return nil
50
+ end
51
+ end
52
+ def set workspace = 0, key, hash
53
+ hash.merge! 'time' => Time.now.to_i
54
+ if @memory[workspace].nil?
55
+ @memory[workspace] = {}
56
+ end
57
+ if @memory[workspace][key]
58
+ @memory[workspace][key] = hash
59
+ else
60
+ @memory[workspace].merge! key => hash
61
+ end
62
+ self.write_memory
63
+ end
64
+ end
@@ -0,0 +1,187 @@
1
+ class Wmctile::Router < Wmctile::Class
2
+ ##################################
3
+ ## init ##########################
4
+ ##################################
5
+ def initialize
6
+ @settings = Wmctile::Settings.new
7
+ @all_workspaces = false
8
+ end
9
+ ##################################
10
+ ## main dispatch method ##########
11
+ ##################################
12
+ def dispatch args = []
13
+ if args.length
14
+ main_arg = args[0]
15
+ if ['--all-workspaces', '-a'].include? main_arg
16
+ @all_workspaces = true
17
+ drop = 2
18
+ main_arg = args[1]
19
+ else
20
+ @all_workspaces = false
21
+ drop = 1
22
+ end
23
+ if main_arg and !['dispatch', 'initialize', 'wm', 'wt', 'memory'].include? main_arg and self.respond_to? main_arg
24
+ self.send main_arg, *args.drop(drop)
25
+ else
26
+ self.help
27
+ end
28
+ else
29
+ self.help
30
+ end
31
+ end
32
+ ##################################
33
+ ## object getter methods #########
34
+ ##################################
35
+ def wm
36
+ @wm || @wm = Wmctile::WindowManager.new(@settings)
37
+ end
38
+ def wt
39
+ # @wm might be nil
40
+ @wt || @wt = Wmctile::WindowTiler.new(@settings, self.memory, @wm)
41
+ end
42
+ def memory
43
+ @memory || @memory = Wmctile::Memory.new
44
+ end
45
+ ##################################
46
+ ## actual command-line methods ###
47
+ ##################################
48
+ def help args = nil
49
+ puts <<-eos
50
+ wmctile version 0.1.1
51
+
52
+ usage:
53
+ wmctile [--option1, --option2, ...] <command> ['argument1', 'argument2', ...]
54
+
55
+ examples:
56
+ wmctile snap 'left' 'terminator'
57
+ wmctile summon --all-workspaces ':ACTIVE:'
58
+
59
+ options:
60
+ --all-workspaces, -a
61
+ Use all workspaces when searching for windows.
62
+
63
+ commands:
64
+ summon 'window_string'
65
+ Summons a window matching 'window_str'.
66
+
67
+ summon_or_run 'window_string' 'command_to_run'
68
+ Summons a window matching 'window_string'. If no window is found, the 'command_to_run' is run.
69
+
70
+ switch_to 'window_string'
71
+ Switches to a window matching 'window_string'.
72
+
73
+ switch_to_or_run 'window_string' 'command_to_run'
74
+ Switches to a window matching 'window_string'. If no window is found, the 'command_to_run' is run.
75
+
76
+ maximize 'window_string'
77
+ Maximizes a window matching 'window_string'.
78
+
79
+ unmaximize 'window_string'
80
+ Unmaximizes a window matching 'window_string'.
81
+
82
+ shade 'window_string'
83
+ Shades a window matching 'window_string'.
84
+
85
+ unshade 'window_string'
86
+ Unshades a window matching 'window_string'.
87
+
88
+ unshade_last_shaded
89
+ Unshades the last shaded window on active workspace.
90
+
91
+ snap 'where' 'window_string' ['portion']
92
+ Snaps a window matching 'window_string' to occupy the 'where' 'portion' of the screen.
93
+ 'where' can be one of 'left', 'right', 'top', 'bottom'
94
+ 'portion' is a float number with the default of 0.5
95
+
96
+ resize 'where' ['portion']
97
+ Resizes the last performed action (snap/tile etc.) on active workspace.
98
+ 'where' can be one of 'left', 'right', 'top', 'bottom'
99
+ The action depends on the previously performed action. When you resize 'left' a previous snap 'left', you're shrinking the window. When you resize 'left' a previous snap 'right', you're increasing the size of the window.
100
+ 'portion' is a float number with the default of 0.01 by which to edit the previous portion of the screen
101
+
102
+ resize_snap 'where' ['portion']
103
+ Resizes the last performed snap on active workspace. Arguments are the same as in resize command.
104
+
105
+ additional information:
106
+ To use the active window, pass ':ACTIVE:' as the 'window_string' argument.
107
+ eos
108
+ end
109
+ def summon window_str
110
+ window = self.wm.find_in_windows window_str, @all_workspaces
111
+ if window
112
+ window.summon
113
+ return true
114
+ else
115
+ return false
116
+ end
117
+ end
118
+ def summon_or_run window_str, cmd_to_run
119
+ unless self.summon window_str
120
+ self.cmd "#{ cmd_to_run } > /dev/null &"
121
+ end
122
+ end
123
+ def switch_to window_str
124
+ window = self.wm.find_in_windows window_str, @all_workspaces
125
+ if window
126
+ window.switch_to
127
+ return true
128
+ else
129
+ return false
130
+ end
131
+ end
132
+ def switch_to_or_run window_str, cmd_to_run
133
+ unless self.switch_to window_str
134
+ self.cmd "#{ cmd_to_run } > /dev/null &"
135
+ end
136
+ end
137
+ def maximize window_str
138
+ window = self.wm.get_window window_str
139
+ if window
140
+ window.maximize
141
+ end
142
+ end
143
+ def unmaximize window_str
144
+ window = self.wm.get_window window_str
145
+ if window
146
+ window.unmaximize
147
+ end
148
+ end
149
+ def shade window_str
150
+ window = self.wm.get_window window_str
151
+ if window
152
+ window.shade
153
+ self.memory.set self.wm.workspace, 'shade', {
154
+ 'window_id' => window.id
155
+ }
156
+ end
157
+ end
158
+ def unshade window_str
159
+ window = self.wm.get_window window_str
160
+ if window
161
+ window.unshade
162
+ self.memory.set self.wm.workspace, 'unshade', {
163
+ 'window_id' => window.id
164
+ }
165
+ end
166
+ end
167
+ def unshade_last_shaded
168
+ win_id = self.memory.get self.wm.workspace, 'shade', 'window_id'
169
+ window = Wmctile::Window.new win_id, @settings
170
+ if window
171
+ window.unshade
172
+ self.memory.set self.wm.workspace, 'unshade', {
173
+ 'window_id' => window.id
174
+ }
175
+ end
176
+ end
177
+ def snap where = 'left', window_str = nil, portion = 0.5
178
+ self.wt.snap where, window_str, portion
179
+ end
180
+ def resize where = 'left', portion = 0.01
181
+ self.wt.resize where, portion
182
+ end
183
+ def resize_snap where = 'left', portion = 0.01
184
+ self.wt.resize_snap where, portion
185
+ end
186
+
187
+ end
@@ -0,0 +1,56 @@
1
+ require 'yaml'
2
+
3
+ class Wmctile::Settings < Wmctile::Class
4
+ def method_missing sym, *args, &block
5
+ return false
6
+ end
7
+
8
+ def initialize
9
+ path = File.expand_path '~/.config/wmctile/wmctile-settings.yml'
10
+ if not File.exist? path
11
+ raw_settings = self.create_new_settings path
12
+ end
13
+ raw_settings ||= File.read path
14
+ settings = YAML.load(raw_settings)
15
+ if settings
16
+ settings.each { |name, value|
17
+ instance_variable_set("@#{name}", value)
18
+ self.class.class_eval { attr_reader name.intern }
19
+ }
20
+ end
21
+ end
22
+
23
+ def test_requirements
24
+ req = ['xrandr', 'wmctrl', 'dmenu']
25
+ ret = req.reject { |r| self.cmd("which #{ r }").length > 0 }
26
+ return ret
27
+ end
28
+ def create_new_settings path
29
+ req = self.test_requirements
30
+ unless req.nil? or req.length == 0
31
+ puts <<-eos
32
+ You don't have #{ req.join(', ') } installed. Wmctile can't run without that.
33
+
34
+ To fix this on Ubuntu, run:
35
+
36
+ sudo apt-get install #{ req.join(' ') }
37
+ eos
38
+ exit
39
+ end
40
+ dir_path = path[/(.*)\/wmctile-settings.yml/, 1]
41
+ if not Dir.exists? dir_path
42
+ Dir.mkdir dir_path
43
+ end
44
+ out_file = File.new path, 'w'
45
+ out_file.puts self.default_settings.to_yaml
46
+ out_file.close
47
+ end
48
+ def default_settings
49
+ {
50
+ :window_border => 1,
51
+ :panel_height => 24,
52
+ :panel_width => 0,
53
+ :hostname => self.cmd('hostname')
54
+ }
55
+ end
56
+ end
@@ -0,0 +1,69 @@
1
+ class Wmctile::Window < Wmctile::Class
2
+ attr_accessor :id, :name, :title
3
+
4
+ def initialize win_string, settings
5
+ @default_movement = { :x => 0, :y => 0, :width => '-1', :height => '-1' }
6
+ @settings = settings
7
+ @id = win_string[/0x[\d\w]{8}/]
8
+ self.get_name_and_title win_string
9
+ end
10
+ def get_name_and_title win_string
11
+ if win_string == @id
12
+ @name = ''
13
+ @title = ''
14
+ else
15
+ after_id_and_workspace = win_string[14..-1].split(/\s+#{ @settings.hostname }\s+/, 2)
16
+ @name = after_id_and_workspace[0]
17
+ @title = after_id_and_workspace[1]
18
+ end
19
+ end
20
+ def dmenu_item
21
+ unless @dmenu_item
22
+ str = "#{ @id } #{ @name } #{ @title }"
23
+ @dmenu_item = Dmenu::Item.new str, self
24
+ end
25
+ @dmenu_item
26
+ end
27
+ def get_name
28
+ if @name == ''
29
+ self.get_name_and_title self.cmd('wmctrl -lx | grep ' + @id)
30
+ end
31
+ @name
32
+ end
33
+ def get_name_length
34
+ @name.length
35
+ end
36
+ def set_name_length name_length
37
+ @name += ' '*(name_length - @name.length)
38
+ end
39
+ def wmctrl wm_cmd = '', summon = false
40
+ self.cmd "wmctrl -i#{ summon ? 'R' : 'r' } #{ @id } #{ wm_cmd }"
41
+ return self # return self so that commands can be chained
42
+ end
43
+ def move how_to_move = {}
44
+ how_to_move = @default_movement.merge! how_to_move
45
+ cmd = "-e 0,#{ how_to_move[:x].to_i },#{ how_to_move[:y].to_i },#{ how_to_move[:width].to_i },#{ how_to_move[:height].to_i }"
46
+ self.unshade
47
+ self.unmaximize
48
+ self.wmctrl cmd
49
+ end
50
+ def shade
51
+ self.wmctrl '-b add,shaded'
52
+ end
53
+ def unshade
54
+ self.wmctrl '-b remove,shaded'
55
+ end
56
+ def summon
57
+ self.wmctrl '', true
58
+ end
59
+ def switch_to
60
+ self.cmd "wmctrl -ia #{ @id }"
61
+ return self
62
+ end
63
+ def maximize
64
+ self.wmctrl '-b add,maximized_vert,maximized_horz'
65
+ end
66
+ def unmaximize
67
+ self.wmctrl '-b remove,maximized_vert,maximized_horz'
68
+ end
69
+ end
@@ -0,0 +1,174 @@
1
+ class Wmctile::WindowManager < Wmctile::ClassWithDmenu
2
+ attr_accessor :w, :h, :workspace, :windows
3
+ ##################################
4
+ ## init ##########################
5
+ ##################################
6
+ def initialize settings
7
+ @settings = settings
8
+ self.init_dimensions
9
+ end
10
+ def init_dimensions
11
+ # legacy (but fast) method via wmctrl
12
+ # dimensions = cmd("wmctrl -d | awk '{ print $9 }' | head -n1").split('x')
13
+ # xrandr is slower, but offers more information
14
+ dimensions = cmd("xrandr | grep -E '\sconnected\s[0-9]+x[0-9]+\+0' | awk '{print $3}' | awk -F'+' '{print $1}'").split('x')
15
+ @w = dimensions[0].to_i - 2*@settings.window_border
16
+ @h = dimensions[1].to_i - 2*@settings.window_border - @settings.panel_height
17
+ @workspace = cmd("wmctrl -d | grep '\*' | awk '{ print $1 }'").to_i
18
+ end
19
+ ##################################
20
+ ## dimension getters #############
21
+ ##################################
22
+ def width portion = 1
23
+ @w * portion
24
+ end
25
+ def height portion = 1
26
+ @h * portion
27
+ end
28
+ ##################################
29
+ ## window getters ################
30
+ ##################################
31
+ def get_window window_str = nil, all_workspaces = false
32
+ if window_str.nil?
33
+ window = self.ask_for_window all_workspaces
34
+ else
35
+ if window_str == ':ACTIVE:'
36
+ window = self.get_active_window
37
+ else
38
+ window = self.find_window window_str, all_workspaces
39
+ unless window
40
+ # does window_str have an icon bundle in it? (aka evince.Evince)
41
+ if window_str =~ /[a-z0-9]+\.[a-z0-9]+/i
42
+ icon = window_str.split('.').first
43
+ else
44
+ icon = nil
45
+ end
46
+ self.notify 'No window found', "#{ window_str }", icon
47
+ end
48
+ end
49
+ end
50
+ window
51
+ end
52
+ def get_active_window
53
+ win_id = self.cmd('wmctrl -a :ACTIVE: -v 2>&1').split('Using window: ').last
54
+ Wmctile::Window.new win_id, @settings
55
+ end
56
+ def find_window window_string, all_workspaces = false
57
+ cmd = "wmctrl -lx | grep -F #{ window_string }"
58
+ cmd += ' | grep -E \'0x\w+\s+' + @workspace.to_s + '\s+\'' unless all_workspaces
59
+ window_string = self.cmd cmd
60
+ window_string = window_string.split("\n").first
61
+ if window_string.nil?
62
+ return nil
63
+ else
64
+ return Wmctile::Window.new window_string, @settings
65
+ end
66
+ end
67
+ def find_windows window_string, all_workspaces = false
68
+ cmd = "wmctrl -lx | grep -F #{ window_string }"
69
+ cmd += ' | grep -E \'0x\w+\s+' + @workspace.to_s + '\s+\'' unless all_workspaces
70
+ window_strings = self.cmd cmd
71
+ window_strings = window_strings.split("\n")
72
+ if window_string.nil?
73
+ return nil
74
+ else
75
+ return window_strings.map { |w| Wmctile::Window.new w, @settings }
76
+ end
77
+ end
78
+ def find_in_windows window_string, all_workspaces = false
79
+ if window_string.nil?
80
+ self.ask_for_window all_workspaces
81
+ else
82
+ windows = self.find_windows window_string, all_workspaces
83
+ if windows
84
+ ids = windows.collect(&:id)
85
+ active_win = self.get_active_window
86
+ if ids.include? active_win.id
87
+ # cycle through the windows
88
+ i = ids.index active_win.id
89
+ # try the next one
90
+ if ids[i+1]
91
+ window = windows[i+1]
92
+ # fallback to the first one
93
+ else
94
+ window = windows.first
95
+ end
96
+ else
97
+ # switch to the first one
98
+ window = windows.first
99
+ end
100
+ return window
101
+ end
102
+ return nil
103
+ end
104
+ end
105
+ def ask_for_window all_workspaces = false
106
+ self.dmenu self.windows.map(&:dmenu_item)
107
+ end
108
+ ##################################
109
+ ## window lists ##################
110
+ ##################################
111
+ def build_win_list all_workspaces = false
112
+ unless all_workspaces
113
+ variable_name = '@windows_on_workspace'
114
+ else
115
+ variable_name = '@windows_all'
116
+ end
117
+ unless instance_variable_get(variable_name)
118
+ unless all_workspaces
119
+ cmd = "wmctrl -lx | grep \" #{ @workspace } \""
120
+ else
121
+ cmd = "wmctrl -lx"
122
+ end
123
+ arr = cmd(cmd).split("\n")
124
+
125
+ new_list = arr.map { |w| Wmctile::Window.new(w, @settings) }
126
+ name_length = new_list.map(&:get_name_length).max
127
+ new_list.each { |w| w.set_name_length(name_length) }
128
+
129
+ instance_variable_set(variable_name, new_list)
130
+ end
131
+ instance_variable_get(variable_name)
132
+ end
133
+ def windows all_workspaces = false
134
+ unless all_workspaces
135
+ variable_name = '@windows_on_workspace'
136
+ else
137
+ variable_name = '@windows_all'
138
+ end
139
+ unless instance_variable_get(variable_name)
140
+ self.build_win_list all_workspaces
141
+ else
142
+ instance_variable_get(variable_name)
143
+ end
144
+ end
145
+ ##################################
146
+ ## window size calculators #######
147
+ ##################################
148
+ def calculate_snap where, portion = 0.5
149
+ return case where
150
+ when 'left'
151
+ {
152
+ :x => @settings.panel_width, :y => @settings.panel_height,
153
+ :height => self.height, :width => self.width(portion)
154
+ }
155
+ when 'right'
156
+ {
157
+ :x => self.width(portion), :y => @settings.panel_height,
158
+ :height => self.height, :width => self.width(1-portion)
159
+ }
160
+ when 'top'
161
+ {
162
+ :x => @settings.panel_width, :y => @settings.panel_height,
163
+ :height => self.height(portion), :width => self.width
164
+ }
165
+ when 'bottom'
166
+ {
167
+ :x => @settings.panel_width, :y => @settings.panel_height + self.height(1-portion),
168
+ :height => self.height(portion), :width => self.width
169
+ }
170
+ else
171
+ nil
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,95 @@
1
+ class Wmctile::WindowTiler < Wmctile::Class
2
+ ##################################
3
+ ## init ##########################
4
+ ##################################
5
+ def initialize settings, memory, wm = nil
6
+ @settings = settings
7
+ @memory = memory
8
+ @wm = wm
9
+ end
10
+ ##################################
11
+ ## object getter methods #########
12
+ ##################################
13
+ def wm
14
+ @wm || @wm = Wmctile::WindowManager.new(@settings)
15
+ end
16
+ def memory
17
+ @memory || @memory = Wmctile::Memory.new
18
+ end
19
+ ##################################
20
+ ## actual snapping methods #######
21
+ ##################################
22
+ def snap where = 'left', window_str = nil, portion = 0.5
23
+ window = self.wm.get_window window_str
24
+ if window
25
+ how_to_move = self.wm.calculate_snap where, portion.to_f
26
+ if how_to_move
27
+ window.move how_to_move
28
+ self.memory.set self.wm.workspace, 'snap', {
29
+ 'where' => where, 'portion' => portion, 'window_id' => window.id
30
+ }
31
+ end
32
+ end
33
+ end
34
+ def resize where = 'left', portion = 0.01
35
+ portion = portion.to_f
36
+ # what are we moving? the last one used from these:
37
+ methods = ['snap']
38
+ freshest_meth = nil
39
+ freshest_time = 0
40
+ methods.each do |meth|
41
+ time = self.memory.get self.wm.workspace, meth, 'time'
42
+ if time > freshest_time
43
+ freshest_time = time
44
+ freshest_meth = meth
45
+ end
46
+ end
47
+ # ok, got it, it's freshest_meth
48
+ self.send "resize_#{ freshest_meth }", where, portion
49
+ end
50
+ def resize_snap where = 'left', portion = 0.01
51
+ portion = portion.to_f
52
+ info = self.memory.get self.wm.workspace, 'snap'
53
+ if info.nil?
54
+ return nil
55
+ end
56
+ negative = case info['where']
57
+ when 'left'
58
+ if where == 'left'
59
+ true
60
+ elsif where == 'right'
61
+ false
62
+ else
63
+ nil
64
+ end
65
+ when 'right'
66
+ if where == 'left'
67
+ false
68
+ elsif where == 'right'
69
+ true
70
+ else
71
+ nil
72
+ end
73
+ when 'top'
74
+ if where == 'bottom'
75
+ false
76
+ elsif where == 'top'
77
+ true
78
+ else
79
+ nil
80
+ end
81
+ when 'bottom'
82
+ if where == 'top'
83
+ false
84
+ elsif where == 'bottom'
85
+ true
86
+ else
87
+ nil
88
+ end
89
+ end
90
+ unless negative.nil?
91
+ portion = -portion if negative
92
+ self.snap info['where'], info['window_id'], info['portion']+portion
93
+ end
94
+ end
95
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wmctile
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - mreq
@@ -30,7 +30,16 @@ executables: []
30
30
  extensions: []
31
31
  extra_rdoc_files: []
32
32
  files:
33
+ - bin/wmctile
33
34
  - lib/wmctile.rb
35
+ - lib/wmctile/class.rb
36
+ - lib/wmctile/class_with_dmenu.rb
37
+ - lib/wmctile/memory.rb
38
+ - lib/wmctile/router.rb
39
+ - lib/wmctile/settings.rb
40
+ - lib/wmctile/window.rb
41
+ - lib/wmctile/window_manager.rb
42
+ - lib/wmctile/window_tiler.rb
34
43
  homepage: http://mreq.github.io/wmctile
35
44
  licenses:
36
45
  - GPL-2