rumai 2.1.0 → 3.0.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/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
|