rumai 2.1.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CREDITS +1 -0
- data/doc/api/classes/Integer.html +5 -5
- data/doc/api/classes/Rumai.html +178 -215
- data/doc/api/classes/Rumai/Area.html +194 -126
- data/doc/api/classes/Rumai/Chain.html +21 -21
- data/doc/api/classes/Rumai/Client.html +506 -142
- data/doc/api/classes/Rumai/ClientContainer.html +22 -22
- data/doc/api/classes/Rumai/IXP/Agent.html +55 -55
- data/doc/api/classes/Rumai/IXP/Agent/FidStream.html +30 -30
- data/doc/api/classes/Rumai/IXP/Agent/MODES.html +5 -5
- data/doc/api/classes/Rumai/IXP/Fcall.html +25 -25
- data/doc/api/classes/Rumai/IXP/Stat.html +5 -5
- data/doc/api/classes/Rumai/IXP/Stream.html +5 -5
- data/doc/api/classes/Rumai/IXP/Struct.html +20 -20
- data/doc/api/classes/Rumai/IXP/Struct/Field.html +30 -30
- data/doc/api/classes/Rumai/IXP/Struct/Field/CounteeField.html +10 -10
- data/doc/api/classes/Rumai/IXP/Struct/Field/CounterField.html +5 -5
- data/doc/api/classes/Rumai/IXP/Terror.html +5 -5
- data/doc/api/classes/Rumai/Node.html +45 -45
- data/doc/api/classes/Rumai/View.html +226 -125
- data/doc/api/classes/Rumai/WidgetImpl.html +1 -1
- data/doc/api/classes/String.html +10 -10
- data/doc/api/classes/Time.html +10 -10
- data/doc/api/created.rid +1 -1
- data/doc/api/files/CREDITS.html +4 -1
- data/doc/api/files/lib/rumai/fs_rb.html +1 -1
- data/doc/api/files/lib/rumai/wm_rb.html +1 -1
- data/doc/api/files/lib/rumai_rb.html +1 -1
- data/doc/api/panel/search_index.js +1 -1
- data/doc/history.erb +63 -0
- data/doc/index.erb +2 -2
- data/doc/index.xhtml +215 -67
- data/doc/intro.erb +4 -1
- data/doc/usage.erb +1 -1
- data/lib/rumai.rb +2 -2
- data/lib/rumai/wm.rb +200 -130
- metadata +2 -2
data/doc/intro.erb
CHANGED
@@ -10,8 +10,11 @@
|
|
10
10
|
%|chapter "Introduction"
|
11
11
|
%|project
|
12
12
|
<%= $project %> is a [Ruby](<%= ruby_url %>) interface to the [wmii](<%= wmii_url %>) window manager.
|
13
|
+
|
13
14
|
* It excels at dynamic arrangement of clients, columns, views, and tags.
|
14
|
-
|
15
|
+
|
16
|
+
* It provides an <%= xref 'shell', 'interactive shell' %> for live entertainment and experimentation.
|
17
|
+
|
15
18
|
* It contains a pure Ruby client for the [9P2000 protocol](<%= p9p_url %>) on which wmii's [IXP file-system interface](<%= wmii_ixp_url %>) is built.
|
16
19
|
|
17
20
|
These features distinguish <%= $project %> from the competition:
|
data/doc/usage.erb
CHANGED
data/lib/rumai.rb
CHANGED
@@ -8,8 +8,8 @@ gem 'inochi', '~> 1'
|
|
8
8
|
require 'inochi'
|
9
9
|
|
10
10
|
Inochi.init :Rumai,
|
11
|
-
:version => '
|
12
|
-
:release => '2009-05-
|
11
|
+
:version => '3.0.0',
|
12
|
+
:release => '2009-05-11',
|
13
13
|
:website => 'http://snk.tuxfamily.org/lib/rumai/',
|
14
14
|
:tagline => 'Ruby interface to the wmii window manager',
|
15
15
|
:develop => {
|
data/lib/rumai/wm.rb
CHANGED
@@ -15,67 +15,11 @@ class Object #:nodoc:
|
|
15
15
|
end
|
16
16
|
|
17
17
|
module Rumai
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def fs
|
24
|
-
ROOT
|
25
|
-
end
|
26
|
-
|
27
|
-
# Returns the current set of tags.
|
28
|
-
def tags
|
29
|
-
fs.tag.entries.sort - %w[sel]
|
30
|
-
end
|
31
|
-
|
32
|
-
# Returns the current set of views.
|
33
|
-
def views
|
34
|
-
tags.map! {|t| View.new t }
|
35
|
-
end
|
36
|
-
|
37
|
-
module ClientContainer
|
38
|
-
# see definition below!
|
39
|
-
end
|
40
|
-
|
41
|
-
include ClientContainer
|
42
|
-
|
43
|
-
# Returns the IDs of the current set of clients.
|
44
|
-
def client_ids
|
45
|
-
fs.client.entries - %w[sel]
|
46
|
-
end
|
47
|
-
|
48
|
-
# Returns the name of the currently focused tag.
|
49
|
-
def curr_tag
|
50
|
-
curr_view.id
|
51
|
-
end
|
52
|
-
|
53
|
-
# Returns the name of the next tag.
|
54
|
-
def next_tag
|
55
|
-
next_view.id
|
56
|
-
end
|
57
|
-
|
58
|
-
# Returns the name of the previous tag.
|
59
|
-
def prev_tag
|
60
|
-
prev_view.id
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
# multiple client grouping: allows you to group a set of clients
|
65
|
-
# together and perform operations on all of them simultaneously.
|
66
|
-
|
67
|
-
GROUPING_TAG = '@'
|
68
|
-
|
69
|
-
# Returns a list of all grouped clients in
|
70
|
-
# the currently focused view. If there are
|
71
|
-
# no grouped clients, then the currently
|
72
|
-
# focused client is returned in the list.
|
73
|
-
def grouping
|
74
|
-
list = curr_view.clients.select {|c| c.group? }
|
75
|
-
list << curr_client if list.empty? and curr_client.exist?
|
76
|
-
list
|
77
|
-
end
|
78
|
-
|
18
|
+
IXP_FS_ROOT = Node.new('/')
|
19
|
+
FOCUSED_WIDGET_ID = 'sel'.freeze
|
20
|
+
FLOATING_AREA_ID = '~'.freeze
|
21
|
+
CLIENT_GROUPING_TAG = '@'.freeze
|
22
|
+
CLIENT_STICKY_TAG = '/./'.freeze
|
79
23
|
|
80
24
|
# abstraction of WM components
|
81
25
|
|
@@ -118,7 +62,7 @@ module Rumai
|
|
118
62
|
##
|
119
63
|
# The basic building block of the WM hierarchy.
|
120
64
|
#
|
121
|
-
# NOTE: Inheritors must
|
65
|
+
# NOTE: Inheritors must define a 'curr' class method.
|
122
66
|
# NOTE: Inheritors must override the 'focus' method.
|
123
67
|
#
|
124
68
|
module WidgetImpl #:nodoc:
|
@@ -147,11 +91,11 @@ module Rumai
|
|
147
91
|
def initialize id, path_prefix
|
148
92
|
super "#{path_prefix}/#{id}"
|
149
93
|
|
150
|
-
if id
|
94
|
+
if id == FOCUSED_WIDGET_ID and ctl.exist?
|
151
95
|
@id = ctl.read.split.first
|
152
|
-
|
96
|
+
super "#{path_prefix}/#{@id}"
|
153
97
|
else
|
154
|
-
@id =
|
98
|
+
@id = id.to_s
|
155
99
|
end
|
156
100
|
end
|
157
101
|
end
|
@@ -168,7 +112,7 @@ module Rumai
|
|
168
112
|
# Returns the currently focused client.
|
169
113
|
#
|
170
114
|
def self.curr
|
171
|
-
new
|
115
|
+
new FOCUSED_WIDGET_ID
|
172
116
|
end
|
173
117
|
|
174
118
|
include Chain
|
@@ -187,7 +131,7 @@ module Rumai
|
|
187
131
|
#
|
188
132
|
def focus view = nil
|
189
133
|
if exist? and not focus?
|
190
|
-
|
134
|
+
(view ? [view] : self.views).each do |v|
|
191
135
|
if a = self.area(v) and a.exist?
|
192
136
|
v.focus
|
193
137
|
a.focus
|
@@ -200,9 +144,7 @@ module Rumai
|
|
200
144
|
distance = (src - dst).abs
|
201
145
|
direction = src < dst ? :down : :up
|
202
146
|
|
203
|
-
distance.times
|
204
|
-
v.ctl.write "select #{direction}"
|
205
|
-
end
|
147
|
+
distance.times { v.move_focus direction }
|
206
148
|
|
207
149
|
break
|
208
150
|
end
|
@@ -218,6 +160,8 @@ module Rumai
|
|
218
160
|
view.ctl.write "send #{@id} #{dst}"
|
219
161
|
end
|
220
162
|
|
163
|
+
alias move send
|
164
|
+
|
221
165
|
##
|
222
166
|
# Swaps this client with the given destination within the given view.
|
223
167
|
#
|
@@ -233,6 +177,77 @@ module Rumai
|
|
233
177
|
ctl.write :kill
|
234
178
|
end
|
235
179
|
|
180
|
+
##
|
181
|
+
# Terminates this client forcefully.
|
182
|
+
#
|
183
|
+
def slay
|
184
|
+
ctl.write :slay
|
185
|
+
end
|
186
|
+
|
187
|
+
##
|
188
|
+
# Maximizes this client to occupy the entire screen on the current view.
|
189
|
+
#
|
190
|
+
def fullscreen
|
191
|
+
ctl.write 'Fullscreen on'
|
192
|
+
end
|
193
|
+
|
194
|
+
##
|
195
|
+
# Restores this client back to its original size on the current view.
|
196
|
+
#
|
197
|
+
def unfullscreen
|
198
|
+
ctl.write 'Fullscreen off'
|
199
|
+
end
|
200
|
+
|
201
|
+
##
|
202
|
+
# Toggles the fullscreen status of this client on the current view.
|
203
|
+
#
|
204
|
+
def fullscreen!
|
205
|
+
ctl.write 'Fullscreen toggle'
|
206
|
+
end
|
207
|
+
|
208
|
+
##
|
209
|
+
# Checks if this client is currently fullscreen on the current view.
|
210
|
+
#
|
211
|
+
def fullscreen?
|
212
|
+
#
|
213
|
+
# If the client's dimensions match those of the
|
214
|
+
# floating area, then we know it is fullscreen.
|
215
|
+
#
|
216
|
+
View.curr.manifest =~ /^# #{FLOATING_AREA_ID} (\d+) (\d+)\n.*^#{FLOATING_AREA_ID} #{@id} \d+ \d+ \1 \2 /m
|
217
|
+
end
|
218
|
+
|
219
|
+
##
|
220
|
+
# Checks if this client is sticky (appears in all views).
|
221
|
+
#
|
222
|
+
def stick?
|
223
|
+
tags.include? CLIENT_STICKY_TAG
|
224
|
+
end
|
225
|
+
|
226
|
+
##
|
227
|
+
# Makes this client sticky (appears in all views).
|
228
|
+
#
|
229
|
+
def stick
|
230
|
+
tag CLIENT_STICKY_TAG
|
231
|
+
end
|
232
|
+
|
233
|
+
##
|
234
|
+
# Makes this client unsticky (does not appear in all views).
|
235
|
+
#
|
236
|
+
def unstick
|
237
|
+
untag CLIENT_STICKY_TAG
|
238
|
+
end
|
239
|
+
|
240
|
+
##
|
241
|
+
# Toggles the stickyness of this client.
|
242
|
+
#
|
243
|
+
def stick!
|
244
|
+
if stick?
|
245
|
+
unstick
|
246
|
+
else
|
247
|
+
stick
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
236
251
|
# WM hierarchy
|
237
252
|
|
238
253
|
##
|
@@ -304,7 +319,7 @@ module Rumai
|
|
304
319
|
# Checks if this client is included in the current grouping.
|
305
320
|
#
|
306
321
|
def group?
|
307
|
-
tags.include?
|
322
|
+
tags.include? CLIENT_GROUPING_TAG
|
308
323
|
end
|
309
324
|
|
310
325
|
##
|
@@ -312,7 +327,7 @@ module Rumai
|
|
312
327
|
#
|
313
328
|
def group
|
314
329
|
with_tags do
|
315
|
-
push
|
330
|
+
push CLIENT_GROUPING_TAG
|
316
331
|
end
|
317
332
|
end
|
318
333
|
|
@@ -320,13 +335,13 @@ module Rumai
|
|
320
335
|
# Removes this client to the current grouping.
|
321
336
|
#
|
322
337
|
def ungroup
|
323
|
-
untag
|
338
|
+
untag CLIENT_GROUPING_TAG
|
324
339
|
end
|
325
340
|
|
326
341
|
##
|
327
342
|
# Toggles the presence of this client in the current grouping.
|
328
343
|
#
|
329
|
-
def
|
344
|
+
def group!
|
330
345
|
if group?
|
331
346
|
ungroup
|
332
347
|
else
|
@@ -336,10 +351,13 @@ module Rumai
|
|
336
351
|
|
337
352
|
private
|
338
353
|
|
354
|
+
##
|
355
|
+
# Returns the wmii ID of the given area.
|
356
|
+
#
|
339
357
|
def area_to_id area_or_id
|
340
358
|
if area_or_id.respond_to? :id
|
341
359
|
id = area_or_id.id
|
342
|
-
id ==
|
360
|
+
id == FLOATING_AREA_ID ? :toggle : id
|
343
361
|
else
|
344
362
|
area_or_id
|
345
363
|
end
|
@@ -365,7 +383,7 @@ module Rumai
|
|
365
383
|
end
|
366
384
|
|
367
385
|
# multiple client grouping
|
368
|
-
%w[group ungroup
|
386
|
+
%w[group ungroup group!].each do |meth|
|
369
387
|
define_method meth do
|
370
388
|
clients.each do |c|
|
371
389
|
c.__send__ meth
|
@@ -399,17 +417,19 @@ module Rumai
|
|
399
417
|
##
|
400
418
|
# Checks if this area is the floating area.
|
401
419
|
#
|
402
|
-
def
|
403
|
-
@id ==
|
420
|
+
def floating?
|
421
|
+
@id == FLOATING_AREA_ID
|
404
422
|
end
|
405
423
|
|
406
424
|
##
|
407
425
|
# Checks if this is a managed area (a column).
|
408
426
|
#
|
409
427
|
def column?
|
410
|
-
not
|
428
|
+
not floating?
|
411
429
|
end
|
412
430
|
|
431
|
+
alias managed? column?
|
432
|
+
|
413
433
|
include WidgetImpl
|
414
434
|
|
415
435
|
##
|
@@ -419,6 +439,13 @@ module Rumai
|
|
419
439
|
View.curr.area_of_client Client.curr
|
420
440
|
end
|
421
441
|
|
442
|
+
##
|
443
|
+
# Returns the floating area in the given view.
|
444
|
+
#
|
445
|
+
def self.floating view = View.curr
|
446
|
+
new FLOATING_AREA_ID, view
|
447
|
+
end
|
448
|
+
|
422
449
|
include Chain
|
423
450
|
|
424
451
|
##
|
@@ -487,11 +514,10 @@ module Rumai
|
|
487
514
|
|
488
515
|
insert clients
|
489
516
|
|
490
|
-
#
|
491
|
-
# area to reflect the tail-wise insertion
|
517
|
+
# move inserted clients to bottom
|
492
518
|
clients.each_with_index do |c, i|
|
493
519
|
until c.id == self.client_ids[-i.succ]
|
494
|
-
c.
|
520
|
+
c.send :down
|
495
521
|
end
|
496
522
|
end
|
497
523
|
end
|
@@ -520,11 +546,10 @@ module Rumai
|
|
520
546
|
|
521
547
|
insert clients
|
522
548
|
|
523
|
-
#
|
524
|
-
# area to reflect the head-wise insertion
|
549
|
+
# move inserted clients to top
|
525
550
|
clients.each_with_index do |c, i|
|
526
551
|
until c.id == self.client_ids[i]
|
527
|
-
c.
|
552
|
+
c.send :up
|
528
553
|
end
|
529
554
|
end
|
530
555
|
end
|
@@ -601,14 +626,14 @@ module Rumai
|
|
601
626
|
# Returns the currently focused view.
|
602
627
|
#
|
603
628
|
def self.curr
|
604
|
-
new
|
629
|
+
new FOCUSED_WIDGET_ID
|
605
630
|
end
|
606
631
|
|
607
632
|
##
|
608
633
|
# Focuses this view.
|
609
634
|
#
|
610
635
|
def focus
|
611
|
-
|
636
|
+
IXP_FS_ROOT.ctl.write "view #{@id}"
|
612
637
|
end
|
613
638
|
|
614
639
|
include Chain
|
@@ -643,12 +668,21 @@ module Rumai
|
|
643
668
|
super view_id, '/tag'
|
644
669
|
end
|
645
670
|
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
671
|
+
# WM operations
|
672
|
+
|
673
|
+
##
|
674
|
+
# Returns the manifest of all areas and clients in this view.
|
675
|
+
#
|
676
|
+
def manifest
|
677
|
+
index.read || ''
|
678
|
+
end
|
679
|
+
|
680
|
+
##
|
681
|
+
# Moves the focus from the current client in the given direction.
|
682
|
+
#
|
683
|
+
def select direction
|
684
|
+
ctl.write "select #{direction}"
|
685
|
+
end
|
652
686
|
|
653
687
|
# WM hierarchy
|
654
688
|
|
@@ -673,9 +707,7 @@ module Rumai
|
|
673
707
|
# Returns the IDs of all areas in this view.
|
674
708
|
#
|
675
709
|
def area_ids
|
676
|
-
|
677
|
-
ids.unshift '~' # the floating area
|
678
|
-
ids
|
710
|
+
manifest.scan(/^# (\d+)/).flatten.unshift(FLOATING_AREA_ID)
|
679
711
|
end
|
680
712
|
|
681
713
|
##
|
@@ -688,8 +720,8 @@ module Rumai
|
|
688
720
|
##
|
689
721
|
# Returns the floating area of this view.
|
690
722
|
#
|
691
|
-
def
|
692
|
-
|
723
|
+
def floating_area
|
724
|
+
Area.floating self
|
693
725
|
end
|
694
726
|
|
695
727
|
##
|
@@ -699,6 +731,8 @@ module Rumai
|
|
699
731
|
areas[1..-1]
|
700
732
|
end
|
701
733
|
|
734
|
+
alias managed_areas columns
|
735
|
+
|
702
736
|
##
|
703
737
|
# Resiliently iterates through possibly destructive changes to
|
704
738
|
# each column. That is, if the given block creates new
|
@@ -719,6 +753,8 @@ module Rumai
|
|
719
753
|
end
|
720
754
|
end
|
721
755
|
|
756
|
+
alias each_managed_area each_column
|
757
|
+
|
722
758
|
# visual arrangement of clients
|
723
759
|
|
724
760
|
##
|
@@ -731,17 +767,23 @@ module Rumai
|
|
731
767
|
#
|
732
768
|
def arrange_as_larswm
|
733
769
|
maintain_focus do
|
734
|
-
float, main, *extra = areas
|
735
|
-
|
736
770
|
# keep only one client in the primary column
|
771
|
+
main = Area.new(1, self)
|
737
772
|
main.length = 1
|
773
|
+
main.layout = :default
|
774
|
+
|
775
|
+
# collapse remaining areas into secondary column
|
776
|
+
extra = columns[1..-1]
|
738
777
|
|
739
778
|
if extra.length > 1
|
740
|
-
# collapse remaining areas into secondary column
|
741
779
|
extra.reverse.each_cons(2) do |src, dst|
|
742
780
|
dst.concat src
|
743
781
|
end
|
744
782
|
end
|
783
|
+
|
784
|
+
if dock = extra.first
|
785
|
+
dock.layout = :default
|
786
|
+
end
|
745
787
|
end
|
746
788
|
end
|
747
789
|
|
@@ -823,7 +865,7 @@ module Rumai
|
|
823
865
|
# before the given block was executed.
|
824
866
|
#
|
825
867
|
def maintain_focus
|
826
|
-
c =
|
868
|
+
c = Client.curr
|
827
869
|
yield
|
828
870
|
c.focus
|
829
871
|
end
|
@@ -836,47 +878,75 @@ module Rumai
|
|
836
878
|
end
|
837
879
|
end
|
838
880
|
|
839
|
-
#
|
840
|
-
|
841
|
-
# provide easy access to container state information
|
842
|
-
[Client, Area, View].each {|c| c.extend ExportInstanceMethods }
|
881
|
+
# access to global WM state
|
843
882
|
|
844
|
-
|
845
|
-
|
883
|
+
##
|
884
|
+
# Returns the root of IXP file system hierarchy.
|
885
|
+
#
|
886
|
+
def fs
|
887
|
+
IXP_FS_ROOT
|
846
888
|
end
|
847
889
|
|
848
|
-
|
849
|
-
|
890
|
+
##
|
891
|
+
# Returns the current set of tags.
|
892
|
+
#
|
893
|
+
def tags
|
894
|
+
ary = IXP_FS_ROOT.tag.entries.sort
|
895
|
+
ary.delete FOCUSED_WIDGET_ID
|
896
|
+
ary
|
850
897
|
end
|
851
898
|
|
852
|
-
|
853
|
-
|
899
|
+
##
|
900
|
+
# Returns the current set of views.
|
901
|
+
#
|
902
|
+
def views
|
903
|
+
tags.map! {|t| View.new t }
|
854
904
|
end
|
855
905
|
|
856
|
-
|
857
|
-
Area.curr
|
858
|
-
end
|
906
|
+
include ClientContainer
|
859
907
|
|
860
|
-
|
861
|
-
|
862
|
-
|
908
|
+
##
|
909
|
+
# Returns the IDs of the current set of clients.
|
910
|
+
#
|
911
|
+
def client_ids
|
912
|
+
ary = IXP_FS_ROOT.client.entries
|
913
|
+
ary.delete FOCUSED_WIDGET_ID
|
914
|
+
ary
|
915
|
+
end
|
863
916
|
|
864
|
-
def
|
865
|
-
|
866
|
-
end
|
917
|
+
def curr_client ; Client.curr ; end
|
918
|
+
def next_client ; curr_client.next ; end
|
919
|
+
def prev_client ; curr_client.prev ; end
|
867
920
|
|
868
|
-
def
|
869
|
-
|
870
|
-
end
|
921
|
+
def curr_area ; Area.curr ; end
|
922
|
+
def next_area ; curr_area.next ; end
|
923
|
+
def prev_area ; curr_area.prev ; end
|
871
924
|
|
872
|
-
def
|
873
|
-
|
874
|
-
end
|
925
|
+
def curr_view ; View.curr ; end
|
926
|
+
def next_view ; curr_view.next ; end
|
927
|
+
def prev_view ; curr_view.prev ; end
|
875
928
|
|
876
|
-
def
|
877
|
-
|
929
|
+
def curr_tag ; curr_view.id ; end
|
930
|
+
def next_tag ; next_view.id ; end
|
931
|
+
def prev_tag ; prev_view.id ; end
|
932
|
+
|
933
|
+
##
|
934
|
+
# Returns a list of all grouped clients in
|
935
|
+
# the currently focused view. If there are
|
936
|
+
# no grouped clients, then the currently
|
937
|
+
# focused client is returned in the list.
|
938
|
+
#
|
939
|
+
def grouping
|
940
|
+
list = curr_view.clients.select {|c| c.group? }
|
941
|
+
list << curr_client if list.empty? and curr_client.exist?
|
942
|
+
list
|
878
943
|
end
|
879
944
|
|
945
|
+
# shortcuts for interactive WM manipulation (via IRB)
|
946
|
+
|
947
|
+
# provide easy access to container state information
|
948
|
+
[Client, Area, View].each {|c| c.extend ExportInstanceMethods }
|
949
|
+
|
880
950
|
def focus_client id
|
881
951
|
Client.focus id
|
882
952
|
end
|
@@ -890,5 +960,5 @@ module Rumai
|
|
890
960
|
end
|
891
961
|
|
892
962
|
# provide easy access to this module's instance methods
|
893
|
-
module_function(*instance_methods)
|
963
|
+
module_function(*instance_methods(false))
|
894
964
|
end
|