dock_driver 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/dock_driver.rb +1 -0
- data/lib/dock_driver/constants.rb +2 -2
- data/lib/dock_driver/dock.rb +119 -115
- data/lib/dock_driver/template/dzen2.rb +3 -3
- data/lib/dock_driver/workspace_pager.rb +139 -129
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8600dffd45322b1eae3efa01d035ed3d7d8d5ea7
|
4
|
+
data.tar.gz: fd0e8cec47d932eddc17210b67e2202db4ca87f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b216ed2f6a4abb071412d62a02d04a213c750a04608dc0aa0e160c078c03af74c5ae5ce4a771fd5deb081317148ead5728b8af0daef0d35e03c9bb59ce709406
|
7
|
+
data.tar.gz: 71a3b065b49212d697c2ec0e497be896901492d9282c90c13829609745072ea0ded8849b8e4a714ba01200b53cc79493dcd68b3508b1d9e3c7a2fc46844ba516
|
data/lib/dock_driver.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
module DockDriver
|
3
3
|
|
4
4
|
# Project version.
|
5
|
-
VERSION = '0.3.
|
5
|
+
VERSION = '0.3.4'
|
6
6
|
|
7
7
|
# Project revision.
|
8
|
-
REVISION = %$Revision:
|
8
|
+
REVISION = %$Revision: 842a417fe636 $
|
9
9
|
|
10
10
|
# The default location of a user's config file.
|
11
11
|
USER_CONFIG_FILE = Pathname( '~/.dock_driver.yml' ).expand_path
|
data/lib/dock_driver/dock.rb
CHANGED
@@ -4,118 +4,122 @@ require 'singleton'
|
|
4
4
|
|
5
5
|
module DockDriver
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
end
|
7
|
+
# Manages the dock process and templating.
|
8
|
+
class Dock
|
9
|
+
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
extend Loggability
|
13
|
+
log_to :dock_driver
|
14
|
+
|
15
|
+
#####################################################################
|
16
|
+
### C O N F I G U R A B I L I T Y A P I
|
17
|
+
#####################################################################
|
18
|
+
|
19
|
+
extend Configurability
|
20
|
+
config_key :dock
|
21
|
+
|
22
|
+
class << self
|
23
|
+
# The loaded config.
|
24
|
+
attr_accessor :config
|
25
|
+
# The dock command to run and pipe the template result to.
|
26
|
+
attr_accessor :command
|
27
|
+
# The configuration for each user-specified DockItem.
|
28
|
+
attr_accessor :items
|
29
|
+
# The dock's output raw ERB template string.
|
30
|
+
attr_accessor :template
|
31
|
+
# Icon Color Set
|
32
|
+
attr_accessor :icon_color
|
33
|
+
end
|
34
|
+
|
35
|
+
# The default configuration for this class.
|
36
|
+
CONFIG_DEFAULTS = {
|
37
|
+
:items => [],
|
38
|
+
:command => 'dzen2 -dock -fg white -bg black -ta l',
|
39
|
+
:template => '<%= time %>'
|
40
|
+
}
|
41
|
+
|
42
|
+
# Configure the class.
|
43
|
+
def self::configure( section )
|
44
|
+
self.config = CONFIG_DEFAULTS.merge( section || {} )
|
45
|
+
self.command = self.config[:command]
|
46
|
+
self.items = self.config[:items] || {}
|
47
|
+
self.template = self.config[:template]
|
48
|
+
end
|
49
|
+
|
50
|
+
#####################################################################
|
51
|
+
### D O C K A P I
|
52
|
+
#####################################################################
|
53
|
+
|
54
|
+
# A hash of the dock items in use.
|
55
|
+
attr_accessor :items
|
56
|
+
|
57
|
+
# A bog-standard constructor.
|
58
|
+
def initialize #:nodoc:
|
59
|
+
@items = {}
|
60
|
+
@lock = Mutex.new
|
61
|
+
end
|
62
|
+
|
63
|
+
# Lazily execute the dock command.
|
64
|
+
def pipe
|
65
|
+
return @pipe ||= IO.popen( self.class.command, 'w' )
|
66
|
+
end
|
67
|
+
|
68
|
+
# Listen to this dock's items, printing to the dock command when
|
69
|
+
# appropriate.
|
70
|
+
def update( obj = self )
|
71
|
+
@lock.synchronize do
|
72
|
+
begin
|
73
|
+
self.pipe.puts Template.render(
|
74
|
+
self.class.template, self.items )
|
75
|
+
rescue Exception => e
|
76
|
+
self.log.error "Unable to write to the dock."
|
77
|
+
self.log.error e.message
|
78
|
+
$stderr.puts e.backtrace
|
79
|
+
exit
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Start or restart the dock.
|
85
|
+
def run
|
86
|
+
self.log.debug "Building items from config."
|
87
|
+
|
88
|
+
self.items.map { |name,item| item.thread.kill }
|
89
|
+
self.items = self.class.items.inject( {} ) do |hash,opts|
|
90
|
+
item = DockItem.new( opts )
|
91
|
+
item.add_observer self
|
92
|
+
hash[item.name] = item
|
93
|
+
hash
|
94
|
+
end
|
95
|
+
|
96
|
+
self.log.debug "Starting items."
|
97
|
+
self.items.map { |name,item| item.thread.run }
|
98
|
+
end
|
99
|
+
|
100
|
+
# Restart the dock.
|
101
|
+
def restart
|
102
|
+
self.log.debug 'Killed.'
|
103
|
+
self.items.map { |name,item| item.thread.kill }
|
104
|
+
self.items.clear
|
105
|
+
@pipe.close if @pipe and not @pipe.closed?
|
106
|
+
@pipe = nil
|
107
|
+
self.run
|
108
|
+
end
|
109
|
+
|
110
|
+
# Shut down the dock gracefully.
|
111
|
+
def kill
|
112
|
+
begin
|
113
|
+
self.log.debug 'Killed.'
|
114
|
+
rescue ThreadError
|
115
|
+
# We can't write to the log from the trap context.
|
116
|
+
end
|
117
|
+
self.items.map { |name,item| item.thread.kill }
|
118
|
+
self.items.clear
|
119
|
+
@pipe.close if @pipe and not @pipe.closed?
|
120
|
+
@pipe = nil
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
@@ -108,7 +108,7 @@ module DockDriver::Template::Dzen2
|
|
108
108
|
i > v
|
109
109
|
end
|
110
110
|
color = colors[t.first]
|
111
|
-
|
111
|
+
|
112
112
|
return value if color.nil?
|
113
113
|
return "^fg(%s)%s^fg()" % [color,value]
|
114
114
|
rescue Exception
|
@@ -130,7 +130,7 @@ module DockDriver::Template::Dzen2
|
|
130
130
|
# <%= i3_button( 'firefox', 'globe' ) %>
|
131
131
|
#
|
132
132
|
def button( cmd, icon_name = 'cogwheel' )
|
133
|
-
return "^ca(1
|
133
|
+
return "^ca(1,%s)%s^ca()" % [cmd, icon( icon_name )]
|
134
134
|
end
|
135
135
|
|
136
136
|
# Methods to add to the including class.
|
@@ -150,4 +150,4 @@ module DockDriver::Template::Dzen2
|
|
150
150
|
klass.extend ClassMethods
|
151
151
|
end
|
152
152
|
|
153
|
-
end
|
153
|
+
end
|
@@ -4,132 +4,142 @@ require 'singleton'
|
|
4
4
|
|
5
5
|
module DockDriver
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
7
|
+
# Provides a list of workspaces as numbered rectangles that shows the
|
8
|
+
# number and presence of workspaces, the focused workspace, and any
|
9
|
+
# workspaces marked urgent.
|
10
|
+
# Example:
|
11
|
+
#
|
12
|
+
# <%= pager %>
|
13
|
+
#
|
14
|
+
class WorkspacePager
|
15
|
+
|
16
|
+
include Observable
|
17
|
+
include Singleton
|
18
|
+
|
19
|
+
extend Loggability
|
20
|
+
log_to :dock_driver
|
21
|
+
|
22
|
+
extend Configurability
|
23
|
+
config_key :pager
|
24
|
+
|
25
|
+
# Defaults for Configurability
|
26
|
+
CONFIG_DEFAULTS = {
|
27
|
+
:format => "^ca(1,i3-msg workspace %s)^fg(%s)^%s(14x14)^p(-10)" +
|
28
|
+
"^ib(1)^fg(%s)%s^fg()^p(6)^fg()^ca()",
|
29
|
+
:fg => '#808080',
|
30
|
+
:bg => '#303030',
|
31
|
+
:focused_fg => '#ffffff',
|
32
|
+
:focused_bg => '#505050',
|
33
|
+
:urgent_fg => '#800000',
|
34
|
+
:urgent_bg => '#F00000'
|
35
|
+
}
|
36
|
+
|
37
|
+
class << self
|
38
|
+
# The loaded config
|
39
|
+
attr_accessor :config
|
40
|
+
# The format string for dzen2.
|
41
|
+
attr_accessor :format
|
42
|
+
# A Foreground color for normal workspace squares.
|
43
|
+
attr_accessor :fg
|
44
|
+
# A Foreground color for normal workspace squares.
|
45
|
+
attr_accessor :bg
|
46
|
+
# A Foreground color for focused workspace squares.
|
47
|
+
attr_accessor :focused_fg
|
48
|
+
# A Foreground color for focused workspace squares.
|
49
|
+
attr_accessor :focused_bg
|
50
|
+
# A Foreground color for urgent workspace squares.
|
51
|
+
attr_accessor :urgent_fg
|
52
|
+
# A Foreground color for urgent workspace squares.
|
53
|
+
attr_accessor :urgent_bg
|
54
|
+
end
|
55
|
+
|
56
|
+
# Merge in what Configurability finds.
|
57
|
+
def self::configure( section )
|
58
|
+
self.config = CONFIG_DEFAULTS.merge( section || {} )
|
59
|
+
self.format = self.config[:format]
|
60
|
+
self.fg = self.config[:fg]
|
61
|
+
self.bg = self.config[:bg]
|
62
|
+
self.focused_fg = self.config[:focused_fg]
|
63
|
+
self.focused_bg = self.config[:focused_bg]
|
64
|
+
self.urgent_fg = self.config[:urgent_fg]
|
65
|
+
self.urgent_bg = self.config[:urgent_bg]
|
66
|
+
end
|
67
|
+
|
68
|
+
# A list of workspaces.
|
69
|
+
attr_accessor :workspaces
|
70
|
+
|
71
|
+
# A boring constructor.
|
72
|
+
def initialize
|
73
|
+
self.log.debug "WorkspacePager::new"
|
74
|
+
@workspaces = []
|
75
|
+
@thread = nil
|
76
|
+
@i3 = nil
|
77
|
+
end
|
78
|
+
|
79
|
+
# Lazily create the thread to update the workspaces as necessary.
|
80
|
+
def thread
|
81
|
+
return @thread ||= Thread.new { loop { wait_for_event } }
|
82
|
+
end
|
83
|
+
|
84
|
+
# Lazily connect to i3.
|
85
|
+
def i3
|
86
|
+
if @i3.nil?
|
87
|
+
@i3 = I3.new
|
88
|
+
@i3.subscribe_workspaces
|
89
|
+
self.update
|
90
|
+
end
|
91
|
+
return @i3
|
92
|
+
rescue Exception => e
|
93
|
+
self.log.debug "The pager was unable to connect to i3 over IPC."
|
94
|
+
self.log.debug e
|
95
|
+
end
|
96
|
+
|
97
|
+
# Update the workspace list.
|
98
|
+
def update
|
99
|
+
self.workspaces = self.i3.get_workspaces.sort { |a,b| a['num'] <=> b['num'] }
|
100
|
+
self.changed
|
101
|
+
self.notify_observers
|
102
|
+
end
|
103
|
+
|
104
|
+
# Return the pager as a formatted string for dzen2.
|
105
|
+
def to_s
|
106
|
+
return '' unless self.workspaces
|
107
|
+
return self.workspaces.inject( '' ) do |str,space|
|
108
|
+
if space['focused']
|
109
|
+
fg = self.class.focused_fg
|
110
|
+
bg = self.class.focused_bg
|
111
|
+
op = 'r' # a filled rectangle
|
112
|
+
elsif space['urgent']
|
113
|
+
fg = self.class.urgent_fg
|
114
|
+
bg = self.class.urgent_bg
|
115
|
+
op = 'r' # a filled rectangle
|
116
|
+
else
|
117
|
+
fg = self.class.fg
|
118
|
+
bg = self.class.bg
|
119
|
+
op = 'ro' # a rectangle outline
|
120
|
+
end
|
121
|
+
str += self.class.format %
|
122
|
+
[space['num'], bg, op, fg, space['num']]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
#######
|
127
|
+
private
|
128
|
+
#######
|
129
|
+
|
130
|
+
# Wait for workspace events.
|
131
|
+
def wait_for_event
|
132
|
+
begin
|
133
|
+
self.i3.wait_for_event( I3::EVENT_WORKSPACE )
|
134
|
+
self.update
|
135
|
+
rescue Exception => e
|
136
|
+
@i3 = nil
|
137
|
+
self.log.debug "The pager was unable to communicate with i3 over IPC."
|
138
|
+
self.log.debug e
|
139
|
+
sleep 1
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dock_driver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Hix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: trollop
|