ffi-tk 2010.01.02 → 2010.02

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.
@@ -35,9 +35,9 @@ module Tk
35
35
  end
36
36
 
37
37
  # Retrieves the value of selection from window's display and returns it as a
38
- # result. Selection defaults to PRIMARY and window defaults to “.”.
38
+ # result. Selection defaults to PRIMARY and window defaults to ".".
39
39
  # Type specifies the form in which the selection is to be returned (the
40
- # desired “target” for conversion, in ICCCM terminology), and should be
40
+ # desired "target" for conversion, in ICCCM terminology), and should be
41
41
  # an atom name such as STRING or FILE_NAME; see the Inter-Client
42
42
  # Communication Conventions Manual for complete details.
43
43
  # Type defaults to STRING.
@@ -129,4 +129,4 @@ module Tk
129
129
  end
130
130
  end
131
131
  end
132
- end
132
+ end
@@ -51,8 +51,9 @@ module Tk
51
51
  # application (the name that may be used in send commands to communicate
52
52
  # with the application).
53
53
  # If newName is specified, then the name of the application is changed to
54
- # newName. If the given name is already in use, then a suffix of the form “
55
- # #2” or #3” is appended in order to make the name unique.
54
+ # newName.
55
+ # If the given name is already in use, then a suffix of the form "#2" or
56
+ # "#3" is appended in order to make the name unique.
56
57
  # The command's result is the name actually chosen.
57
58
  # newName should not start with a capital letter.
58
59
  # This will interfere with option processing, since names starting with
@@ -90,7 +91,7 @@ module Tk
90
91
  # If the window argument is omitted, it defaults to the main window.
91
92
  # If the number argument is omitted, the current value of the scaling
92
93
  # factor is returned.
93
- # A point is a unit of measurement equal to 1/72 inch.
94
+ # A "point" is a unit of measurement equal to 1/72 inch.
94
95
  # A scaling factor of 1.0 corresponds to 1 pixel per point, which is
95
96
  # equivalent to a standard 72 dpi monitor.
96
97
  # A scaling factor of 1.25 would mean 1.25 pixels per point, which is the
@@ -434,7 +434,7 @@ module Tk
434
434
  # Returns the number of pixels in window corresponding to the distance
435
435
  # given by number.
436
436
  # Number may be specified in any of the forms acceptable to Tk_GetPixels,
437
- # such as 2.0c or 1i”.
437
+ # such as "2.0c" or "1i".
438
438
  # The result is rounded to the nearest integer value; for a fractional
439
439
  # result, use winfo fpixels.
440
440
  def pixels(window, number)
@@ -665,4 +665,4 @@ module Tk
665
665
  Tk.execute(:winfo, :y, window)
666
666
  end
667
667
  end
668
- end
668
+ end
@@ -14,6 +14,8 @@ module Tk
14
14
  TclString.new('{' << map(&:to_tcl).compact.join(' ') << '}')
15
15
  end
16
16
 
17
+ # try to convert to a Hash.
18
+ # it may return an Array if this contains none.
17
19
  def tcl_options_to_hash(hints = {})
18
20
  if first.respond_to?(:to_ary)
19
21
  hash = {}
@@ -36,9 +38,8 @@ module Tk
36
38
  end
37
39
 
38
40
  hash
39
- else
41
+ elsif first =~ /^-/
40
42
  ::Hash[each_slice(2).map{|key, value|
41
-
42
43
  key = key.sub(/^-/, '').to_sym
43
44
 
44
45
  case hint = hints[key]
@@ -52,6 +53,8 @@ module Tk
52
53
  [key, value]
53
54
  end
54
55
  }]
56
+ else
57
+ self
55
58
  end
56
59
  end
57
60
  end
@@ -95,7 +98,7 @@ module Tk
95
98
 
96
99
  module String
97
100
  def to_tcl
98
- TclString.new('"' << gsub(/[\[\]$"\\]/, '\\\\\&') << '"')
101
+ TclString.new('"' << gsub(/[\[\]{}$"\\]/, '\\\\\&') << '"')
99
102
  end
100
103
 
101
104
  def to_tcl_option
@@ -33,8 +33,8 @@ module Tk
33
33
  ['%K', :String, :keysym ],
34
34
  ['%N', :Integer, :keysym_number ],
35
35
  ['%P', :String, :property ],
36
- ['%R', :Integer, :root ],
37
- ['%S', :Integer, :subwindow ],
36
+ ['%R', :String, :root ],
37
+ ['%S', :String, :subwindow ],
38
38
  ['%T', :Integer, :type ],
39
39
  ['%W', :String, :window_path ],
40
40
  ['%X', :Integer, :x_root ],
@@ -45,7 +45,8 @@ module Tk
45
45
  super id, sequence
46
46
 
47
47
  PROPERTIES.each do |code, conv, name|
48
- converted = __send__(conv, properties.shift)
48
+ value = properties.shift
49
+ converted = __send__(conv, value)
49
50
  next if converted == '??'
50
51
  self[name] = converted
51
52
  end
@@ -54,6 +55,36 @@ module Tk
54
55
  def call
55
56
  Handler.invoke(id, self) if id
56
57
  end
58
+
59
+ # Try to resend the event with as much information preserved as possible.
60
+ # Unfortunately that doesn't seem to be easy.
61
+ def resend(widget, virtual, changes = {})
62
+ original = {}
63
+ members.each do |name|
64
+ value = self[name]
65
+
66
+ case name
67
+ when :id, :sequence, :border_width, :button, :count, :focus, :height,
68
+ :keycode, :keysym, :keysym_number, :mode, :mousewheel_delta,
69
+ :override_redirect, :place, :property, :root, :send_event,
70
+ :subwindow, :type, :unicode, :width, :window, :window_path
71
+ when :x_root
72
+ original[:rootx] = value
73
+ when :y_root
74
+ original[:rooty] = value
75
+ when :detail
76
+ original[name] = value if value
77
+ else
78
+ original[name] = value
79
+ end
80
+ end
81
+
82
+ Event.generate(widget, virtual, original.merge(changes))
83
+ end
84
+
85
+ def widget
86
+ Tk.widgets[window_path]
87
+ end
57
88
  end
58
89
  end
59
90
  end
@@ -4,6 +4,7 @@ module Tk
4
4
  data = Data::PROPERTIES.transpose[0].join(' ').gsub(/%/, '%%')
5
5
  @callback = %(bind %s %s { ::RubyFFI::event %d %s #{data} })
6
6
  @store = []
7
+ @bound = {}
7
8
  @mutex = Mutex.new
8
9
 
9
10
  module_function
@@ -27,6 +28,7 @@ module Tk
27
28
  def register(tag, sequence, &block)
28
29
  id = register_block(block)
29
30
  Tk.interp.eval(@callback % [tag, sequence, id, sequence])
31
+ @bound[[tag, sequence]] = block
30
32
  id
31
33
  end
32
34
 
@@ -36,8 +38,15 @@ module Tk
36
38
  id
37
39
  end
38
40
 
39
- def unregister(id)
40
- @store[id] = nil
41
+ def unregister(tag, sequence)
42
+ key = [tag, sequence]
43
+
44
+ if block = @bound[key]
45
+ Tk.execute(:bind, tag, sequence, nil)
46
+ id = @store.index(block)
47
+ @store[id] = nil
48
+ @bound.delete(key)
49
+ end
41
50
  end
42
51
  end
43
52
  end
@@ -30,6 +30,9 @@ module FFI
30
30
  Tcl.new_string_obj(ruby_obj, ruby_obj.bytesize)
31
31
  when Fixnum
32
32
  Tcl.new_int_obj(ruby_obj)
33
+ when Exception
34
+ string = [ruby_obj.message, *ruby_obj.backtrace].join("\n")
35
+ Tcl.new_string_obj(string, string.bytesize)
33
36
  else
34
37
  if ruby_obj.respond_to?(:to_tcl)
35
38
  ruby_obj.to_tcl
data/lib/ffi-tk/ffi/tk.rb CHANGED
@@ -3,11 +3,50 @@ module FFI
3
3
  extend FFI::Library
4
4
  ffi_lib 'libtk8.5.so', 'libtk.so', *::Tk::LIBPATH[:tk]
5
5
 
6
+ class XColor < FFI::Struct
7
+ layout(
8
+ :pixel, :ulong,
9
+ :red, :ushort,
10
+ :green, :ushort,
11
+ :blue, :ushort,
12
+ :flags, :char,
13
+ :pad, :char
14
+ )
15
+
16
+ def red
17
+ self[:red]
18
+ end
19
+
20
+ def green
21
+ self[:green]
22
+ end
23
+
24
+ def blue
25
+ self[:blue]
26
+ end
27
+ end
28
+
29
+ # This is opaque
30
+ class Window < FFI::Struct
31
+ end
32
+
6
33
  attach_function :Tk_Init, [:pointer], :int
34
+ attach_function :Tk_MainWindow, [Tcl::Interp], Window
35
+ attach_function :Tk_GetColor, [Tcl::Interp, Window, name = :string], XColor
7
36
  attach_function :Tk_MainLoop, [], :void
8
37
 
9
38
  module_function
10
39
 
40
+ def get_color(interp, string)
41
+ if ::Tk::RUN_EVENTLOOP_ON_MAIN_THREAD
42
+ XColor.new(Tk_GetColor(interp, Tk_MainWindow(interp), string))
43
+ else
44
+ Tcl.thread_sender.thread_send{
45
+ XColor.new(Tk_GetColor(interp, Tk_MainWindow(interp), string))
46
+ }
47
+ end
48
+ end
49
+
11
50
  def mainloop
12
51
  if ::Tk::RUN_EVENTLOOP_ON_MAIN_THREAD
13
52
  Tk_MainLoop()
data/lib/ffi-tk/tk.rb CHANGED
@@ -124,7 +124,7 @@ module Tk
124
124
 
125
125
  return BREAK
126
126
  rescue => ex
127
- FFI::Tcl::Interp.new(interp).obj_result = ex.message
127
+ FFI::Tcl::Interp.new(interp).obj_result = ex
128
128
  return ERROR
129
129
  end
130
130
  TCL_CALLBACK = method(:tcl_callback)
@@ -145,7 +145,7 @@ module Tk
145
145
 
146
146
  return BREAK
147
147
  rescue => ex
148
- FFI::Tcl::Interp.new(interp).obj_result = ex.message
148
+ FFI::Tcl::Interp.new(interp).obj_result = ex
149
149
  return ERROR
150
150
  end
151
151
  TCL_EVENT = method(:tcl_event)
@@ -1,3 +1,3 @@
1
1
  module FFI::Tk
2
- VERSION = "2010.01.02"
2
+ VERSION = "2010.02"
3
3
  end
@@ -174,7 +174,7 @@ module Tk
174
174
  # unregister_event(name)
175
175
 
176
176
  Event::Handler.register_custom(script) do |id|
177
- code = "%s bind %s %s { puts hi\n::RubyFFI::event %d %s %s }"
177
+ code = "%s bind %s %s { ::RubyFFI::event %d %s %s }"
178
178
  props = Event::Data::PROPERTIES.transpose[0].join(' ')
179
179
  tcl = code % [tk_pathname, tag_or_id, sequence, id, sequence, props]
180
180
  Tk.interp.eval(tcl)
@@ -15,7 +15,7 @@ module Tk
15
15
  end
16
16
  end
17
17
 
18
- # Deselects the checkbutton and sets the associated variable to its off
18
+ # Deselects the checkbutton and sets the associated variable to its "off"
19
19
  # value.
20
20
  def deselect
21
21
  execute_only(:deselect)
@@ -36,12 +36,12 @@ module Tk
36
36
  # Tcl command associated with the checkbutton, if there is one.
37
37
  # The return value is the return value from the Tcl command, or an empty
38
38
  # string if there is no command associated with the checkbutton.
39
- # This command is ignored if the checkbut‐ ton's state is disabled.
39
+ # This command is ignored if the checkbutton's state is disabled.
40
40
  def invoke
41
41
  execute_only(:invoke)
42
42
  end
43
43
 
44
- # Selects the checkbutton and sets the associated variable to its on
44
+ # Selects the checkbutton and sets the associated variable to its "on"
45
45
  # value.
46
46
  def select
47
47
  execute_only(:select)
@@ -20,7 +20,7 @@ module Tk
20
20
  # Sets the active element to the one indicated by index.
21
21
  # If index is outside the range of elements in the listbox then the closest
22
22
  # element is activated.
23
- # The active element is drawn as speci‐ fied by -activestyle when the
23
+ # The active element is drawn as specified by -activestyle when the
24
24
  # widget has the input focus, and its index may be retrieved with the index
25
25
  # active.
26
26
  def activate(index)
@@ -100,7 +100,7 @@ module Tk
100
100
  # of this list).
101
101
  # If option is specified with no value, then the command returns a list
102
102
  # describing the one named option (this list will be identical to the
103
- # correspond‐ ing sublist of the value returned if no option is specified).
103
+ # corresponding sublist of the value returned if no option is specified).
104
104
  # If one or more option-value pairs are specified, then the command
105
105
  # modifies the given widget option(s) to have the given value(s); in this
106
106
  # case the command returns an empty string.
@@ -136,7 +136,7 @@ module Tk
136
136
 
137
137
  # This command computes the difference between its x and y arguments and
138
138
  # the x and y arguments to the last scan mark command for the widget.
139
- # It then adjusts the view by 10 times the dif‐ ference in coordinates.
139
+ # It then adjusts the view by 10 times the difference in coordinates.
140
140
  # This command is typically associated with mouse motion events in the
141
141
  # widget, to produce the effect of dragging the list at high speed through
142
142
  # the window.
@@ -44,7 +44,7 @@ module Tk
44
44
  # This option is not available for separator or tear-off entries.
45
45
  # -bitmap value Specifies a bitmap to display in the menu instead of a
46
46
  # textual label, in any of the forms accepted by Tk_GetBitmap.
47
- # This option overrides the -label option (as controlled by the -com‐ pound
47
+ # This option overrides the -label option (as controlled by the -compound
48
48
  # option) but may be reset to an empty string to enable a textual label to
49
49
  # be displayed.
50
50
  # If a -image option has been specified, it overrides -bitmap.
@@ -58,7 +58,7 @@ module Tk
58
58
  # -compound value Specifies whether the menu entry should display both an
59
59
  # image and text, and if so, where the image should be placed relative to
60
60
  # the text.
61
- # Valid values for this option are bottom, cen‐ ter, left, none, right and
61
+ # Valid values for this option are bottom, center, left, none, right and
62
62
  # top. The default value is none, meaning that the button will display
63
63
  # either an image or text, depending on the values of the -image and
64
64
  # -bitmap options.
@@ -122,7 +122,7 @@ module Tk
122
122
  # bindings will refuse to activate or invoke the entry.
123
123
  # In this state the entry is displayed according to the disabledForeground
124
124
  # option for the menu and the background option from the entry.
125
- # This option is not available for separa‐ tor entries.
125
+ # This option is not available for separator entries.
126
126
  # -underline value Specifies the integer index of a character to underline
127
127
  # in the entry.
128
128
  # This option is also queried by the default bindings and used to implement
@@ -255,7 +255,7 @@ module Tk
255
255
  # Unmap the window so that it is no longer displayed.
256
256
  # If a lower-level cascaded menu is posted, unpost that menu.
257
257
  # Returns an empty string.
258
- # This subcommand does not work on Windows and the Mac‐ intosh, as those
258
+ # This subcommand does not work on Windows and the Macintosh, as those
259
259
  # platforms have their own way of unposting menus.
260
260
  def unpost
261
261
  execute(:unpost)
@@ -263,7 +263,6 @@ module Tk
263
263
 
264
264
  # Returns a decimal string giving the x-coordinate within the menu window
265
265
  # of the leftmost pixel in the entry specified by index.
266
- # │
267
266
  def xposition(index)
268
267
  execute(:xposition, index)
269
268
  end
@@ -299,7 +298,7 @@ module Tk
299
298
  # menus. You create a torn-off menu by invoking the tear-off entry at the
300
299
  # top of an existing menu.
301
300
  # The default bindings will create a new menu that is a copy of the
302
- # original menu and leave it perma‐ nently posted as a top-level window.
301
+ # original menu and leave it permanently posted as a top-level window.
303
302
  # The torn-off menu behaves just the same as the original menu.
304
303
  # and unposts the menu.
305
304
  # If the current menu is a top-level menu posted from a menubutton, then
@@ -62,7 +62,7 @@ module Tk
62
62
 
63
63
  # This command computes the difference between the given coordinates and
64
64
  # the coordinates given to the last sash mark command for the given sash.
65
- # It then moves that sash the computed dif‐ ference.
65
+ # It then moves that sash the computed difference.
66
66
  def sash_dragto(index, x, y)
67
67
  execute_only(:sash, :dragto, index, x, y)
68
68
  end
@@ -84,81 +84,107 @@ module Tk
84
84
  execute(:panecget, window, option.to_tcl_option)
85
85
  end
86
86
 
87
- # Query or modify the management options for window.
88
- # If no option is specified, returns a list describing all of the available
89
- # options for pathName (see Tk_ConfigureInfo for information on the format
87
+ # Query or modify the management options for +window+.
88
+ #
89
+ # If no +options+ is specified, returns a list describing all of the available
90
+ # options for +window+ (see Tk_ConfigureInfo for information on the format
90
91
  # of this list).
91
- # If option is specified with no value, then the command returns a list
92
+ #
93
+ # If +options+ is specified with no value, then the command returns a list
92
94
  # describing the one named option (this list will be identical to the
93
95
  # corresponding sublist of the value returned if no option is specified).
94
- # If one or more option-value pairs are specified, then the command
95
- # modifies the given widget option(s) to have the given value(s); in this
96
- # case the command returns an empty string.
97
- # The following options are supported: -after window Insert the window
98
- # after the window specified.
99
- # window should be the name of a window already managed by pathName.
100
- # -before window Insert the window before the window specified.
101
- # window should be the name of a window already managed by pathName.
102
- # -height size Specify a height for the window.
103
- # The height will be the outer dimension of the window including its
104
- # border, if any.
105
- # If size is an empty string, or if -height is not specified, then the
106
- # height requested internally by the window will be used initially; the
107
- # height may later be adjusted by the movement of sashes in the
108
- # panedwindow. Size may be any value accepted by Tk_GetPixels.
109
- # -hide boolean Controls the visibility of a pane.
110
- # When the boolean is true (according to Tcl_GetBoolean) the pane will not
111
- # be visible, but it will still be maintained in the list of panes.
112
- # -minsize n Specifies that the size of the window cannot be made less
113
- # than n.
114
- # This constraint only affects the size of the widget in the paned
115
- # dimension the x dimension for horizontal panedwin‐ dows, the y
116
- # dimension for vertical panedwindows.
117
- # May be any value accepted by Tk_GetPixels.
118
- # -padx n Specifies a non-negative value indicating how much extra space to
119
- # leave on each side of the window in the X-direction.
120
- # The value may have any of the forms accepted by Tk_GetPixels.
121
- # -pady n Specifies a non-negative value indicating how much extra space to
122
- # leave on each side of the window in the Y-direction.
123
- # The value may have any of the forms accepted by Tk_GetPixels.
124
- # -sticky style If a window's pane is larger than the requested dimensions
125
- # of the window, this option may be used to position (or stretch) the
126
- # window within its pane.
127
- # Style is a string that contains zero or more of the characters n, s, e or
128
- # w. The string can optionally contains spaces or commas, but they are
129
- # ignored. Each letter refers to a side (north, south, east, or west) that
130
- # the window will “stick” to.
131
- # If both n and s (or e and w) are specified, the window will be stretched
132
- # to fill the entire height (or width) of its cavity.
133
- # -stretch when Controls how extra space is allocated to each of the panes.
134
- # When is one of always, first, last, middle, and never.
135
- # The panedwindow will calculate the required size of all its panes.
136
- # Any remaining (or deficit) space will be distributed to those panes
137
- # marked for stretching.
138
- # The space will be distributed based on each panes current ratio of the
139
- # whole. The when values have the following definition: always │ This
140
- # pane will always stretch.
141
- # first │ Only if this pane is the first pane (left-most or top-most)
142
- # will it stretch.
143
- # │ last │ Only if this pane is the last pane (right-most or bottom-most)
144
- # will it stretch.
145
- # This is the default value.
146
- # │ middle │ Only if this pane is not the first or last pane will it
147
- # stretch. never This pane will never stretch.
148
- # -width size Specify a width for the window.
149
- # The width will be the outer dimension of the window including its border,
150
- # if any.
151
- # If size is an empty string, or if -width is not specified, then the width
152
- # requested internally by the window will be used initially; the width may
153
- # later be adjusted by the movement of sashes in the panedwindow.
154
- # Size may be any value accepted by Tk_Get‐ Pixels.
96
+ #
97
+ # If one or more option-value pairs are specified, then the command modifies
98
+ # the given widget option(s) to have the given value(s); in this case the
99
+ # command returns an empty string.
100
+ #
101
+ # The following options are supported:
102
+ # :after window
103
+ # Insert the window after the window specified.
104
+ # window should be the name of a window already managed by +window+.
105
+ #
106
+ # :before window
107
+ # Insert the window before the window specified.
108
+ # window should be the name of a window already managed by +window+.
109
+ #
110
+ # :height size
111
+ # Specify a height for the window.
112
+ # The height will be the outer dimension of the window including its
113
+ # border, if any.
114
+ # If size is an empty string, or if -height is not specified, then the
115
+ # height requested internally by the window will be used initially; the
116
+ # height may later be adjusted by the movement of sashes in the
117
+ # panedwindow. Size may be any value accepted by Tk_GetPixels.
118
+ #
119
+ # :hide boolean
120
+ # Controls the visibility of a pane.
121
+ # When the boolean is true (according to Tcl_GetBoolean) the pane will
122
+ # not be visible, but it will still be maintained in the list of panes.
123
+ #
124
+ # :minsize n
125
+ # Specifies that the size of the window cannot be made less than n.
126
+ # This constraint only affects the size of the widget in the paned
127
+ # dimension -- the x dimension for horizontal panedwindows, the y
128
+ # dimension for vertical panedwindows.
129
+ # May be any value accepted by Tk_GetPixels.
130
+ #
131
+ # :padx n
132
+ # Specifies a non-negative value indicating how much extra space to
133
+ # leave on each side of the window in the X-direction.
134
+ # The value may have any of the forms accepted by Tk_GetPixels.
135
+ #
136
+ # :pady n
137
+ # Specifies a non-negative value indicating how much extra space to
138
+ # leave on each side of the window in the Y-direction.
139
+ # The value may have any of the forms accepted by Tk_GetPixels.
140
+ # :sticky style
141
+ # If a window's pane is larger than the requested dimensions of the
142
+ # window, this option may be used to position (or stretch) the window
143
+ # within its pane.
144
+ # Style is a string that contains zero or more of the characters n, s, e
145
+ # or w.
146
+ # The string can optionally contains spaces or commas, but they are
147
+ # ignored. Each letter refers to a side (north, south, east, or west)
148
+ # that the window will "stick" to.
149
+ # If both n and s (or e and w) are specified, the window will be
150
+ # stretched to fill the entire height (or width) of its cavity.
151
+ # :stretch when
152
+ # Controls how extra space is allocated to each of the panes.
153
+ # When is one of always, first, last, middle, and never.
154
+ # The panedwindow will calculate the required size of all its panes.
155
+ # Any remaining (or deficit) space will be distributed to those panes
156
+ # marked for stretching.
157
+ # The space will be distributed based on each panes current ratio of the
158
+ # whole.
159
+ # The when values have the following definition:
160
+ # :always
161
+ # This pane will always stretch.
162
+ # :first
163
+ # Only if this pane is the first pane (left-most or top-most) will
164
+ # it stretch.
165
+ # :last
166
+ # Only if this pane is the last pane (right-most or bottom-most)
167
+ # will it stretch. This is the default value.
168
+ # :middle
169
+ # Only if this pane is not the first or last pane will it stretch.
170
+ # :never
171
+ # This pane will never stretch.
172
+ #
173
+ # :width size
174
+ # Specify a width for the window.
175
+ # The width will be the outer dimension of the window including its
176
+ # border, if any.
177
+ # If size is an empty string, or if -width is not specified, then the
178
+ # width requested internally by the window will be used initially; the
179
+ # width may later be adjusted by the movement of sashes in the
180
+ # panedwindow. Size may be any value accepted by Tk_GetPixels.
155
181
  def paneconfigure(window, options = None)
156
182
  common_configure([:paneconfigure, window], options)
157
183
  end
158
184
 
159
- # Returns an ordered list of the widgets managed by pathName.
160
- def panes
161
- execute(:panes).to_a
185
+ # Returns an ordered list of the widgets managed by +window+.
186
+ def panes(window = None)
187
+ execute(:panes, window).to_a
162
188
  end
163
189
  end
164
190
  end