tiling 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.
- data/NEWS +3 -0
- data/README.markdown +105 -0
- data/Rakefile +35 -0
- data/TODO +5 -0
- data/VERSION +1 -0
- data/bin/tiling +10 -0
- data/lib/tiling/frame_extents.rb +17 -0
- data/lib/tiling/horizontal_layout.rb +47 -0
- data/lib/tiling/layout.rb +26 -0
- data/lib/tiling/mover.rb +10 -0
- data/lib/tiling/option.rb +52 -0
- data/lib/tiling/vertical_layout.rb +48 -0
- data/lib/tiling/windows.rb +49 -0
- data/lib/tiling/workspace.rb +36 -0
- data/lib/tiling.rb +29 -0
- data/shell/tiling.sh +21 -0
- metadata +82 -0
data/README.markdown
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
TILING
|
2
|
+
================
|
3
|
+
|
4
|
+
Description
|
5
|
+
----------------------
|
6
|
+
**Tiling** provides a *simple window tiling* system for linux.
|
7
|
+
This is for those who cannot (or don't want to) use a tiling window manager like
|
8
|
+
awesome or Xmonad.
|
9
|
+
|
10
|
+
There is no menu nor GUI in **tiling**. This is because I want to keep
|
11
|
+
**tiling** as simple as possible. You just (optionaly) focus a window and
|
12
|
+
press a keyboard shortcut and that's it: all windows in the current virtual
|
13
|
+
desktop are tiled.
|
14
|
+
|
15
|
+
For now **tiling** provides two layouts: horizontal and vertical, where a
|
16
|
+
«master» window occupy the top, or the left, of the screen, while remaining
|
17
|
+
windows share the rest of the screen.
|
18
|
+
|
19
|
+
###Examples
|
20
|
+
|
21
|
+

|
22
|
+
|
23
|
+

|
24
|
+
|
25
|
+

|
26
|
+
|
27
|
+

|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
Install
|
32
|
+
-------------------------
|
33
|
+
|
34
|
+
### Installing the gem
|
35
|
+
|
36
|
+
*Using rvm is highly recommended.*
|
37
|
+
|
38
|
+
If your system ruby is at least 1.9.2 :
|
39
|
+
|
40
|
+
rvm use system
|
41
|
+
gem install tiling
|
42
|
+
|
43
|
+
That's it, go to create keyboard shortcuts. But if your system ruby
|
44
|
+
is older, you'll need the following trick.
|
45
|
+
|
46
|
+
rvm use 1.9.3@global
|
47
|
+
gem install tiling
|
48
|
+
Now, copy the file shell/tiling.sh somewhere in your path (maybe in
|
49
|
+
$HOME/bin) and **edit the last but one line** to reflect your rvm settings.
|
50
|
+
|
51
|
+
### Create keyboard shortcuts
|
52
|
+
|
53
|
+
In Debian, open System > Preferences > Keyboard shortcuts.
|
54
|
+
Click Add to add a new shortcuts. In name, enter «Horizontal layout»,
|
55
|
+
in command, enter «tiling -H» (uppercase H). If you are using tiling.sh,
|
56
|
+
you have to enter «tiling.sh -H» instead of «tiling -H».
|
57
|
+
|
58
|
+
Then close the dialog and make your shortcut, maybe Mod4+h, or Ctrl+Alt+h,
|
59
|
+
or whatever you want.
|
60
|
+
|
61
|
+
Do this again for a second shortcut. Name it «Vertical layout», enter the
|
62
|
+
command «tiling -V» (or «tiling.sh -V») and make the shortcut you want.
|
63
|
+
Note the uppercase V.
|
64
|
+
|
65
|
+
Usage
|
66
|
+
--------------------------
|
67
|
+
|
68
|
+
Easy. Focus a window and type your shortcut.
|
69
|
+
|
70
|
+
Dependencies
|
71
|
+
--------------------------
|
72
|
+
|
73
|
+
ruby >= 1.9.2
|
74
|
+
|
75
|
+
License
|
76
|
+
--------------------------
|
77
|
+
|
78
|
+
MIT
|
79
|
+
|
80
|
+
Copyright (c) 2013 Xavier Nayrac
|
81
|
+
|
82
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
83
|
+
a copy of this software and associated documentation files (the
|
84
|
+
"Software"), to deal in the Software without restriction, including
|
85
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
86
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
87
|
+
permit persons to whom the Software is furnished to do so, subject to
|
88
|
+
the following conditions:
|
89
|
+
|
90
|
+
The above copyright notice and this permission notice shall be included
|
91
|
+
in all copies or substantial portions of the Software.
|
92
|
+
|
93
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
94
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
95
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
96
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
97
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
98
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
99
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
100
|
+
|
101
|
+
Questions and/or Comments
|
102
|
+
--------------------------
|
103
|
+
|
104
|
+
Feel free to email [Xavier Nayrac](mailto:xavier.nayrac@gmail.com)
|
105
|
+
with any questions.
|
data/Rakefile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
|
4
|
+
require 'rake'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
desc 'Test'
|
8
|
+
task :default => :spec
|
9
|
+
|
10
|
+
desc 'Test tiling with rspec'
|
11
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
12
|
+
t.rspec_opts = ['--color']
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Check for code smells'
|
16
|
+
task :reek do
|
17
|
+
puts 'Checking for code smells...'
|
18
|
+
files = Dir.glob 'lib/**/*.rb'
|
19
|
+
# files.delete FILE_TO_EXCLUDE
|
20
|
+
args = files.join(' ')
|
21
|
+
sh "reek --quiet #{args} | ./reek.sed"
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Check refactoring candidates'
|
25
|
+
task :flay do
|
26
|
+
sh "flay lib/*.rb"
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'Build gem & install it'
|
30
|
+
task :install do
|
31
|
+
sh "rm tiling*gem"
|
32
|
+
sh "gem build tiling.gemspec"
|
33
|
+
f = FileList['tiling*gem'].to_a
|
34
|
+
sh "gem install #{f.first}"
|
35
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0
|
data/bin/tiling
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Tiling
|
4
|
+
|
5
|
+
# Public: Décoration de fenêtre.
|
6
|
+
class FrameExtents
|
7
|
+
attr_reader :left, :right, :top, :bottom
|
8
|
+
|
9
|
+
def initialize extents
|
10
|
+
@left = extents[0]
|
11
|
+
@right = extents[1]
|
12
|
+
@top = extents[2]
|
13
|
+
@bottom = extents[3]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Tiling
|
4
|
+
|
5
|
+
# Public: Met en place un layout horizontal.
|
6
|
+
class HorizontalLayout < Layout
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def calculate_master
|
11
|
+
@master[:height_exterior] = (@workspace.height - @workspace.y) / 2
|
12
|
+
ext = FrameExtents.new(@master[:frame_extents])
|
13
|
+
@master[:height] = @master[:height_exterior] - ext.top - ext.bottom
|
14
|
+
@master[:width] = @workspace.width - ext.left - ext.right
|
15
|
+
end
|
16
|
+
|
17
|
+
def position_remaining_windows
|
18
|
+
@real_width = @workspace.width / @windows.count
|
19
|
+
@x = @workspace.x
|
20
|
+
@y = @workspace.y + @master[:height_exterior]
|
21
|
+
@windows.each { |win| position_window win }
|
22
|
+
end
|
23
|
+
|
24
|
+
def position_window win
|
25
|
+
@ext = FrameExtents.new(win[:frame_extents])
|
26
|
+
width = get_win_width
|
27
|
+
height = get_win_height
|
28
|
+
move_resize_window win, width, height
|
29
|
+
@x += @real_width
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_win_width
|
33
|
+
@real_width - @ext.left- @ext.right
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_win_height
|
37
|
+
tmp = @workspace.y + @master[:height_exterior]
|
38
|
+
@workspace.height - tmp - @ext.top - @ext.bottom
|
39
|
+
end
|
40
|
+
|
41
|
+
def move_resize_window win, width, height
|
42
|
+
Mover.move(win[:id], @x, @y, width, height)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Tiling
|
4
|
+
|
5
|
+
# Public: Classe de base pour les layouts.
|
6
|
+
class Layout
|
7
|
+
|
8
|
+
def initialize workspace, windows
|
9
|
+
@workspace = workspace
|
10
|
+
@windows = windows
|
11
|
+
@master = windows.master
|
12
|
+
end
|
13
|
+
|
14
|
+
def lay_master_window
|
15
|
+
calculate_master
|
16
|
+
Mover.move @master[:id], @workspace.x, @workspace.y, @master[:width],
|
17
|
+
@master[:height]
|
18
|
+
end
|
19
|
+
|
20
|
+
def lay_remaining_windows
|
21
|
+
position_remaining_windows unless @windows.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/lib/tiling/mover.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
module Tiling
|
6
|
+
|
7
|
+
# Public: Set the options.
|
8
|
+
class Option
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@options = {horizontal: false, vertical: false, version: false }
|
12
|
+
optparse = OptionParser.new do|opts|
|
13
|
+
opts.on( '-H', '--horizontal', 'Horizontal layout' ) do
|
14
|
+
@options[:horizontal] = true
|
15
|
+
end
|
16
|
+
opts.on( '-V', '--vertical', 'Vertical layout' ) do
|
17
|
+
@options[:vertical] = true
|
18
|
+
end
|
19
|
+
opts.on( '-v', '--version', 'Print version number and exit' ) do
|
20
|
+
@options[:version] = true
|
21
|
+
end
|
22
|
+
opts.on( '-h', '--help', 'Display this screen' ) do
|
23
|
+
puts opts
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
optparse.parse!
|
30
|
+
rescue OptionParser::InvalidOption => e
|
31
|
+
puts e.to_s
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
print_version if @options[:version]
|
36
|
+
end
|
37
|
+
|
38
|
+
def [](key)
|
39
|
+
@options[key]
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def print_version
|
45
|
+
puts "wlayout #{File.read(File.join($WLAYOUT_PATH, 'VERSION')).strip}"
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Tiling
|
4
|
+
|
5
|
+
# Public: Met en place un layout vertical.
|
6
|
+
class VerticalLayout < Layout
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def calculate_master
|
11
|
+
@master[:width_exterior] = (@workspace.width - @workspace.x) / 2
|
12
|
+
ext = FrameExtents.new(@master[:frame_extents])
|
13
|
+
@master[:width] = @master[:width_exterior] - ext.left - ext.right
|
14
|
+
@master[:height] = @workspace.height - ext.top - ext.bottom
|
15
|
+
end
|
16
|
+
|
17
|
+
def position_remaining_windows
|
18
|
+
@real_height = @workspace.height / @windows.count
|
19
|
+
@y = @workspace.y
|
20
|
+
@x = @workspace.x + @master[:width_exterior]
|
21
|
+
@windows.each { |win| position_window win }
|
22
|
+
end
|
23
|
+
|
24
|
+
def position_window win
|
25
|
+
@ext = FrameExtents.new(win[:frame_extents])
|
26
|
+
height = get_win_height
|
27
|
+
width = get_win_width
|
28
|
+
move_resize_window win, width, height
|
29
|
+
@y += @real_height
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_win_height
|
33
|
+
@real_height - @ext.top - @ext.bottom
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_win_width
|
37
|
+
tmp = @workspace.x + @master[:width_exterior]
|
38
|
+
@workspace.width - tmp - @ext.left - @ext.right
|
39
|
+
end
|
40
|
+
|
41
|
+
def move_resize_window win, width, height
|
42
|
+
Mover.move(win[:id], @x, @y, width, height)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Tiling
|
4
|
+
|
5
|
+
# Public: Find our windows.
|
6
|
+
class Windows
|
7
|
+
|
8
|
+
attr_reader :master
|
9
|
+
|
10
|
+
def initialize workspace
|
11
|
+
@workspace = workspace
|
12
|
+
@wm = WMCtrl.instance
|
13
|
+
find_windows
|
14
|
+
end
|
15
|
+
|
16
|
+
def empty?
|
17
|
+
@windows.empty?
|
18
|
+
end
|
19
|
+
|
20
|
+
def count
|
21
|
+
@windows.count
|
22
|
+
end
|
23
|
+
|
24
|
+
def each &block
|
25
|
+
@windows.each &block
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def find_windows
|
31
|
+
@windows = windows_in_active_workspace
|
32
|
+
put_active_window_on_top
|
33
|
+
@master = get_master_window
|
34
|
+
end
|
35
|
+
|
36
|
+
def windows_in_active_workspace
|
37
|
+
@wm.windows.select { |win| win[:desktop] == @workspace.id }
|
38
|
+
end
|
39
|
+
|
40
|
+
def put_active_window_on_top
|
41
|
+
@windows.sort! { |x,y| y[:active] ? 1 : -1 }
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_master_window
|
45
|
+
@windows.slice!(0)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Tiling
|
4
|
+
# Public: Current workspace (virtual desktop) state.
|
5
|
+
class Workspace
|
6
|
+
|
7
|
+
attr_reader :id
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@desktops = WMCtrl.instance.desktops
|
11
|
+
@desktops.each do |desktop|
|
12
|
+
if desktop[:current]
|
13
|
+
@id = desktop[:id]
|
14
|
+
break
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def x
|
20
|
+
@desktops[@id][:workarea][0]
|
21
|
+
end
|
22
|
+
|
23
|
+
def y
|
24
|
+
@desktops[@id][:workarea][1]
|
25
|
+
end
|
26
|
+
|
27
|
+
def width
|
28
|
+
@desktops[@id][:workarea][2]
|
29
|
+
end
|
30
|
+
|
31
|
+
def height
|
32
|
+
@desktops[@id][:workarea][3]
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
data/lib/tiling.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
gem 'ruby-wmctrl', '0.0.5'
|
4
|
+
require 'wmctrl'
|
5
|
+
require 'tiling/workspace'
|
6
|
+
require 'tiling/windows'
|
7
|
+
require 'tiling/layout'
|
8
|
+
require 'tiling/horizontal_layout'
|
9
|
+
require 'tiling/vertical_layout'
|
10
|
+
require 'tiling/mover'
|
11
|
+
require 'tiling/option'
|
12
|
+
require 'tiling/frame_extents'
|
13
|
+
|
14
|
+
|
15
|
+
module Tiling
|
16
|
+
def self.run
|
17
|
+
options = Option.new
|
18
|
+
workspace = Workspace.new
|
19
|
+
windows = Windows.new workspace
|
20
|
+
exit if windows.empty?
|
21
|
+
if options[:vertical]
|
22
|
+
layout = VerticalLayout.new workspace, windows
|
23
|
+
else
|
24
|
+
layout = HorizontalLayout.new workspace, windows
|
25
|
+
end
|
26
|
+
layout.lay_master_window
|
27
|
+
layout.lay_remaining_windows
|
28
|
+
end
|
29
|
+
end
|
data/shell/tiling.sh
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# Load RVM into a shell session *as a function*
|
4
|
+
if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
|
5
|
+
|
6
|
+
# First try to load from a user install
|
7
|
+
source "$HOME/.rvm/scripts/rvm"
|
8
|
+
|
9
|
+
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
|
10
|
+
|
11
|
+
# Then try to load from a root install
|
12
|
+
source "/usr/local/rvm/scripts/rvm"
|
13
|
+
|
14
|
+
else
|
15
|
+
|
16
|
+
printf "ERROR: An RVM installation was not found.\n"
|
17
|
+
|
18
|
+
fi
|
19
|
+
|
20
|
+
rvm use 1.9.3-p374@global
|
21
|
+
tiling $1
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tiling
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Xavier Nayrac
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ruby-wmctrl
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - '='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.0.5
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - '='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.0.5
|
30
|
+
description: ! 'Tiling provides a simple window tiling system for linux.
|
31
|
+
|
32
|
+
This is for those who cannot (or don''t want to) use a tiling window manager like
|
33
|
+
|
34
|
+
awesome or Xmonad.'
|
35
|
+
email: xavier.nayrac@gmail.com
|
36
|
+
executables:
|
37
|
+
- tiling
|
38
|
+
extensions: []
|
39
|
+
extra_rdoc_files: []
|
40
|
+
files:
|
41
|
+
- lib/tiling/option.rb
|
42
|
+
- lib/tiling/windows.rb
|
43
|
+
- lib/tiling/frame_extents.rb
|
44
|
+
- lib/tiling/vertical_layout.rb
|
45
|
+
- lib/tiling/mover.rb
|
46
|
+
- lib/tiling/workspace.rb
|
47
|
+
- lib/tiling/horizontal_layout.rb
|
48
|
+
- lib/tiling/layout.rb
|
49
|
+
- lib/tiling.rb
|
50
|
+
- bin/tiling
|
51
|
+
- shell/tiling.sh
|
52
|
+
- VERSION
|
53
|
+
- NEWS
|
54
|
+
- README.markdown
|
55
|
+
- Rakefile
|
56
|
+
- TODO
|
57
|
+
homepage: https://github.com/lkdjiin/tiling
|
58
|
+
licenses:
|
59
|
+
- MIT
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.9.2
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 1.8.25
|
79
|
+
signing_key:
|
80
|
+
specification_version: 3
|
81
|
+
summary: Some windows layouts for (I hope so) any common linux desktop
|
82
|
+
test_files: []
|