vimamsa 0.1.9 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,3 @@
1
-
2
1
  # Following this example:
3
2
  # https://gabmus.org/posts/create_an_auto-resizing_image_widget_with_gtk3_and_python/
4
3
  class ResizableImage < Gtk::DrawingArea
@@ -18,26 +17,33 @@ class ResizableImage < Gtk::DrawingArea
18
17
  def scale_image()
19
18
  pb = @pixbuf
20
19
  view = @view
21
- imglimit = view.visible_rect.width - 10
20
+ if view.visible_rect.width > 0
21
+ imglimit = view.visible_rect.width - 50
22
+ else
23
+ imglimit = 500
24
+ end
22
25
 
23
26
  if @oldimg.width > imglimit or @oldimg.width < imglimit - 10
24
27
  nwidth = imglimit
25
28
  nwidth = pb.width if pb.width < imglimit
26
29
  nheight = (pb.height * (nwidth.to_f / pb.width)).to_i
30
+ # Ripl.start :binding => binding
31
+
27
32
  pb = pb.scale_simple(nwidth, nheight, GdkPixbuf::InterpType::HYPER)
28
33
  else
29
34
  pb = @oldimg
30
35
  end
31
36
  @draw_image = pb
32
37
  @oldimg = pb
33
- self.set_size_request(pb.width, pb.height)
34
-
38
+ #TODO: Should be better way to compensate for the gutter
39
+ self.set_size_request(pb.width+@view.gutter_width, pb.height)
35
40
  end
36
41
 
37
42
  def do_draw(da, cr)
38
43
  # puts @fpath
39
- cr.set_source_pixbuf(@draw_image, 0, 0)
44
+ # Ripl.start :binding => binding
45
+
46
+ cr.set_source_pixbuf(@draw_image, @view.gutter_width, 0)
40
47
  cr.paint
41
48
  end
42
49
  end
43
-
@@ -16,7 +16,6 @@ module Vimamsa
16
16
  end
17
17
 
18
18
  def add_menu_items()
19
-
20
19
  add_to_menu "File.Example", { :label => "<span foreground='#888888'>Action, [mode] key binding</span>", :action => nil }
21
20
  add_to_menu "File.Save", { :label => "Save", :action => :buf_save }
22
21
  add_to_menu "File.Save as", { :label => "Save As...", :action => :buf_save_as }
@@ -40,14 +39,13 @@ module Vimamsa
40
39
  add_to_menu "Actions.FileHistoryFinder", { :label => "Search files in history", :action => :gui_file_history_finder }
41
40
 
42
41
  add_to_menu "Actions.experimental.Diff", { :label => "Show Diff of\nunsaved changes", :action => :diff_buffer }
43
-
42
+
44
43
  add_to_menu "Actions.experimental.EnableDebug", { :label => "Enable debug", :action => :enable_debug }
45
44
  add_to_menu "Actions.experimental.DisableDebug", { :label => "Disable debug", :action => :disable_debug }
46
45
  add_to_menu "Actions.experimental.ShowImages", { :label => "Show images ⟦img:path⟧", :action => :show_images }
47
-
46
+
48
47
  add_to_menu "Actions.EncryptFile", { :label => "Encrypt file", :action => :encrypt_file }
49
48
  add_to_menu "Help.KeyBindings", { :label => "Show key bindings", :action => :show_key_bindings }
50
-
51
49
 
52
50
  #TODO: :auto_indent_buffer
53
51
 
@@ -55,26 +53,19 @@ module Vimamsa
55
53
 
56
54
  end
57
55
 
58
- def initialize(menubar)
59
- # nfo["file"] = { :items => {}, :label => "File" }
60
- # nfo["actions"] = { :items => {}, :label => "Actions" }
61
- # nfo["help"] = { :items => {}, :label => "Help" }
62
-
56
+ def initialize(menubar, _app)
57
+ @app = _app
63
58
  @nfo = {}
64
59
 
65
60
  add_menu_items
66
61
 
67
- # add_to_menu("help.extra.keybindings", { :label => "Show keybindings" })
68
- # add_to_menu("help.extra.nfo.keybindings", { :label => "Show keybindings" })
69
- # add_to_menu("help.keybindings", { :label => "Show keybindings <span foreground='#888888' >C ? k</span>" }) #font='12' weight='ultrabold'
70
-
71
62
  for k, v in @nfo
72
63
  build_menu(v, menubar)
73
64
  end
74
65
  end
75
66
 
76
67
  def build_menu(nfo, parent)
77
- menu = Gtk::Menu.new
68
+ menu = Gio::Menu.new
78
69
  if nfo[:action]
79
70
  kbd_str = ""
80
71
  for mode_str in ["C", "V"]
@@ -86,24 +77,38 @@ module Vimamsa
86
77
  end
87
78
 
88
79
  label_str = nfo[:label] + kbd_str
89
- menuitem = Gtk::MenuItem.new(:label => label_str)
90
- menuitem.children[0].set_markup(label_str)
91
-
92
- menuitem.signal_connect("activate") do
80
+ actkey = nfo[:action].to_s
81
+ menuitem = Gio::MenuItem.new(label_str, "app.#{actkey}")
82
+
83
+ # This worked in GTK3:
84
+ # But seems there is no way to access the Label object in GTK4
85
+ # menuitem.children[0].set_markup(label_str)
86
+
87
+ act = Gio::SimpleAction.new(actkey)
88
+ @app.add_action(act)
89
+ act.signal_connect "activate" do |_simple_action, _parameter|
93
90
  call_action(nfo[:action])
94
91
  end
95
92
  else
96
- menuitem = Gtk::MenuItem.new(:label => nfo[:label])
97
- menuitem.children[0].set_markup(nfo[:label])
93
+ menuitem = Gio::MenuItem.new(nfo[:label], nil)
98
94
  end
99
95
 
96
+ # Apparently requires Gtk 4.6 to work.
97
+ # According to instructions in: https://discourse.gnome.org/t/gtk4-and-pango-markup-in-menu-items/16082
98
+ # Boolean true here should work but doesn't yet in GTK 4.6. The string version does work.
99
+ menuitem.set_attribute_value("use-markup", "true")
100
+ # menuitem.set_attribute_value("use-markup", true)
101
+ # This might change in the future(?), but the string version still works in gtk-4.13.0 (gtk/gtkmenutrackeritem.c)
102
+
103
+
100
104
  if !nfo[:items].nil? and !nfo[:items].empty?
101
105
  for k2, item in nfo[:items]
102
106
  build_menu(item, menu)
103
107
  end
104
108
  menuitem.submenu = menu
105
109
  end
106
- parent.append(menuitem)
110
+ o = parent.append_item(menuitem)
111
+
107
112
  end
108
113
  end #end class
109
114
  end
@@ -1,4 +1,4 @@
1
- def gui_select_update_window(item_list, jump_keys, select_callback, update_callback, opt={})
1
+ def gui_select_update_window(item_list, jump_keys, select_callback, update_callback, opt = {})
2
2
  $selup = SelectUpdateWindow.new(nil, item_list, jump_keys, select_callback, update_callback, opt)
3
3
  $selup.run
4
4
  # opt fields:
@@ -39,7 +39,7 @@ class SelectUpdateWindow
39
39
  end
40
40
 
41
41
  def initialize(main_window, item_list, jump_keys, select_callback, update_callback, opt = {})
42
- @window = Gtk::Window.new(:toplevel)
42
+ @window = Gtk::Window.new()
43
43
  # @window.screen = main_window.screen
44
44
  @window.title = ""
45
45
  if !opt[:title].nil?
@@ -50,12 +50,23 @@ class SelectUpdateWindow
50
50
  @opt = opt
51
51
 
52
52
  debug item_list.inspect
53
- @update_callback = method(update_callback)
54
- @select_callback = method(select_callback)
53
+
54
+ if select_callback.class == Method
55
+ @select_callback = select_callback
56
+ else
57
+ @select_callback = method(select_callback)
58
+ end
59
+ if update_callback.class == Method
60
+ @update_callback = update_callback
61
+ else
62
+ @update_callback = method(update_callback)
63
+ end
55
64
  # debug @update_callback_m.call("").inspect
56
65
 
57
66
  vbox = Gtk::Box.new(:vertical, 8)
58
- vbox.margin = 8
67
+ vbox.margin_bottom = 8
68
+ vbox.margin_top = 8
69
+
59
70
  @window.add(vbox)
60
71
 
61
72
  @entry = Gtk::SearchEntry.new
@@ -74,24 +85,31 @@ class SelectUpdateWindow
74
85
  # item_list = @update_callback.call("")
75
86
  update_item_list(item_list)
76
87
 
77
- @window.signal_connect("key-press-event") do |_widget, event|
78
- # debug "KEYPRESS 1"
79
- @entry.handle_event(event)
80
- end
88
+ # @window.signal_connect("key-press-event") do |_widget, event| #TODO:gtk4
89
+ # debug "KEYPRESS 1"
90
+ # @entry.handle_event(event)
91
+ # end
92
+
93
+ press = Gtk::EventControllerKey.new
94
+ press.set_propagation_phase(Gtk::PropagationPhase::CAPTURE)
81
95
 
82
- @entry.signal_connect("key_press_event") do |widget, event|
83
- # debug "KEYPRESS 2"
84
- if event.keyval == Gdk::Keyval::KEY_Down
96
+ @entry.add_controller(press)
97
+ # @window.add_controller(press)
98
+ press.signal_connect "key-pressed" do |gesture, keyval, keycode, y|
99
+ name = Gdk::Keyval.to_name(keyval)
100
+ uki = Gdk::Keyval.to_unicode(keyval)
101
+ keystr = uki.chr("UTF-8")
102
+ debug "keyval=#{keyval}"
103
+
104
+ if keyval == Gdk::Keyval::KEY_Down
85
105
  debug "DOWN"
86
106
  set_selected_row(@selected_row + 1)
87
- # fixed = iter[COLUMN_FIXED]
88
-
89
107
  true
90
- elsif event.keyval == Gdk::Keyval::KEY_Up
108
+ elsif keyval == Gdk::Keyval::KEY_Up
91
109
  set_selected_row(@selected_row - 1)
92
110
  debug "UP"
93
111
  true
94
- elsif event.keyval == Gdk::Keyval::KEY_Return
112
+ elsif keyval == Gdk::Keyval::KEY_Return
95
113
  path = Gtk::TreePath.new(@selected_row.to_s)
96
114
  iter = @model.get_iter(path)
97
115
  ret = iter[1]
@@ -99,7 +117,7 @@ class SelectUpdateWindow
99
117
  @window.destroy
100
118
  # debug iter[1].inspect
101
119
  true
102
- elsif event.keyval == Gdk::Keyval::KEY_Escape
120
+ elsif keyval == Gdk::Keyval::KEY_Escape
103
121
  @window.destroy
104
122
  true
105
123
  else
@@ -131,11 +149,12 @@ class SelectUpdateWindow
131
149
 
132
150
  vbox.pack_start(container, :expand => false, :fill => false, :padding => 0)
133
151
  sw = Gtk::ScrolledWindow.new(nil, nil)
134
- sw.shadow_type = :etched_in
152
+ # sw.shadow_type = :etched_in #TODO:gtk4
135
153
  sw.set_policy(:never, :automatic)
136
- vbox.pack_start(sw, :expand => true, :fill => true, :padding => 0)
154
+ vbox.pack_end(sw, :expand => true, :fill => true, :padding => 0)
137
155
 
138
- sw.add(treeview)
156
+ # sw.add(treeview) #TODO:gtk4
157
+ sw.set_child(treeview)
139
158
 
140
159
  if !opt[:columns].nil?
141
160
  for col in opt[:columns]
@@ -168,7 +187,7 @@ class SelectUpdateWindow
168
187
 
169
188
  def run
170
189
  if !@window.visible?
171
- @window.show_all
190
+ @window.show
172
191
  # add_spinner
173
192
  else
174
193
  @window.destroy
@@ -1,80 +1,135 @@
1
-
2
-
3
1
  # class VSourceView < Gtk::TextView
4
2
  class VSourceView < GtkSource::View
5
- attr_accessor :bufo
3
+ attr_accessor :bufo
6
4
  # :highlight_matching_brackets
7
-
5
+
8
6
  # def set_highlight_current_line(vbool)
9
7
  # end
10
-
8
+
11
9
  # def set_show_line_numbers(vbool)
12
10
  # end
13
-
11
+
14
12
  # def highlight_matching_brackets=(vbool)
15
13
  # end
16
-
17
14
 
18
- def initialize(title = nil,bufo=nil)
15
+ # def initialize(title = nil,bufo=nil)
16
+ def initialize(title, bufo)
19
17
  # super(:toplevel)
20
18
  @highlight_matching_brackets = true
19
+ @idle_func_running = false
21
20
  super()
22
21
  @bufo = bufo #object of Buffer class buffer.rb
23
22
  debug "vsource init"
24
23
  @last_keyval = nil
25
24
  @last_event = [nil, nil]
26
- self.drag_dest_add_image_targets
27
- self.drag_dest_add_uri_targets
28
-
29
- signal_connect "button-press-event" do |_widget, event|
30
- if event.button == Gdk::BUTTON_PRIMARY
31
- # debug "Gdk::BUTTON_PRIMARY"
32
- false
33
- elsif event.button == Gdk::BUTTON_SECONDARY
34
- # debug "Gdk::BUTTON_SECONDARY"
35
- true
36
- else
37
- true
38
- end
39
- end
40
-
41
- signal_connect("drag-data-received") do |widget, event, x, y, data, info, time|
42
- puts "drag-data-received"
43
- puts
44
- if data.uris.size >= 1
45
- imgpath = CGI.unescape(data.uris[0])
46
- m = imgpath.match(/^file:\/\/(.*)/)
47
- if m
48
- fp = m[1]
49
- handle_drag_and_drop(fp)
50
- end
51
- end
52
- true
53
- end
54
-
55
- signal_connect("key_press_event") do |widget, event|
56
- handle_key_event(event, :key_press_event)
57
- true
58
- end
59
-
60
- signal_connect("key_release_event") do |widget, event|
61
- handle_key_event(event, :key_release_event)
62
- true
63
- end
25
+ @removed_controllers = []
26
+ self.highlight_current_line = true
27
+
28
+ # self.drag_dest_add_image_targets #TODO:gtk4
29
+ # self.drag_dest_add_uri_targets #TODO:gtk4
30
+
31
+ # signal_connect("drag-data-received") do |widget, event, x, y, data, info, time| #TODO:gtk4
32
+ # puts "drag-data-received"
33
+ # puts
34
+ # if data.uris.size >= 1
35
+ # imgpath = CGI.unescape(data.uris[0])
36
+ # m = imgpath.match(/^file:\/\/(.*)/)
37
+ # if m
38
+ # fp = m[1]
39
+ # handle_drag_and_drop(fp)
40
+ # end
41
+ # end
42
+ # true
43
+ # end
64
44
 
65
45
  signal_connect("move-cursor") do |widget, event|
46
+ debug("MOVE-CURSOR",2)
66
47
  $update_cursor = true
67
48
  false
68
49
  end
69
50
 
51
+ return
52
+
53
+ #TODO:gtk4
70
54
  signal_connect "button-release-event" do |widget, event|
71
- $buffer.set_pos(buffer.cursor_position)
55
+ vma.buf.set_pos(buffer.cursor_position)
72
56
  false
73
57
  end
74
58
  @curpos_mark = nil
75
59
  end
76
60
 
77
- def handle_key_event(event, sig)
61
+ def gutter_width()
62
+ winwidth = width
63
+ view_width = visible_rect.width
64
+ gutter_width = winwidth - view_width
65
+ end
66
+
67
+ def show_controllers
68
+ clist = self.observe_controllers
69
+ (0..(clist.n_items - 1)).each { |x|
70
+ ctr = clist.get_item(x)
71
+ pp ctr
72
+ }
73
+ end
74
+
75
+ def check_controllers
76
+ clist = self.observe_controllers
77
+ to_remove = []
78
+ (0..(clist.n_items - 1)).each { |x|
79
+ ctr = clist.get_item(x)
80
+ # Sometimes a GestureClick EventController appears from somewhere
81
+ # not initiated from this file.
82
+
83
+ # if ctr.class == Gtk::EventControllerKey or ctr.class == Gtk::GestureClick
84
+ if ctr != @click
85
+ # to_remove << ctr if ctr.class != Gtk::GestureDrag
86
+ to_remove << ctr
87
+ end
88
+ }
89
+ if to_remove.size > 0
90
+ debug "Removing controllers:"
91
+ pp to_remove
92
+ to_remove.each { |x|
93
+ # To avoid GC. https://github.com/ruby-gnome/ruby-gnome/issues/15790
94
+ @removed_controllers << x
95
+ self.remove_controller(x)
96
+ }
97
+ end
98
+ end
99
+
100
+ def register_signals()
101
+
102
+ #TODO: Doesn't seem to catch "move-cursor" signal since upgrade to gtk4
103
+ # self.signal_connect("move-cursor") do |widget, event|
104
+ # $update_cursor = true
105
+ # false
106
+ # end
107
+
108
+ check_controllers
109
+ click = Gtk::GestureClick.new
110
+ click.set_propagation_phase(Gtk::PropagationPhase::CAPTURE)
111
+ self.add_controller(click)
112
+ # Detect mouse click
113
+ @click = click
114
+ click.signal_connect "pressed" do |gesture, n_press, x, y, z|
115
+ debug "SourceView, GestureClick x=#{x} y=#{y}"
116
+ pp visible_rect
117
+ winw = width
118
+ view_width = visible_rect.width
119
+ gutter_width = winw - view_width
120
+
121
+ i = get_iter_at_location((x - gutter_width).to_i, (y + visible_rect.y).to_i)
122
+ if !i.nil?
123
+ @bufo.set_pos(i.offset)
124
+ else
125
+ debug "iter nil 0000"
126
+ end
127
+ true
128
+ end
129
+ end
130
+
131
+ # def handle_key_event(event, sig)
132
+ def handle_key_event(keyval, keyname, sig)
78
133
  if $update_cursor
79
134
  curpos = buffer.cursor_position
80
135
  debug "MOVE CURSOR: #{curpos}"
@@ -84,13 +139,14 @@ class VSourceView < GtkSource::View
84
139
  debug $view.visible_rect.inspect
85
140
 
86
141
  debug "key event"
87
- debug event
142
+ # debug event
88
143
 
89
- key_name = event.string
90
- if event.state.control_mask?
91
- key_name = Gdk::Keyval.to_name(event.keyval)
92
- # Gdk::Keyval.to_name()
93
- end
144
+ # key_name = event.string
145
+ #TODO:??
146
+ # if event.state.control_mask?
147
+ # key_name = Gdk::Keyval.to_name(event.keyval)
148
+ # Gdk::Keyval.to_name()
149
+ # end
94
150
 
95
151
  keyval_trans = {}
96
152
  keyval_trans[Gdk::Keyval::KEY_Control_L] = "ctrl"
@@ -121,29 +177,48 @@ class VSourceView < GtkSource::View
121
177
 
122
178
  key_trans = {}
123
179
  key_trans["\e"] = "esc"
124
- tk = keyval_trans[event.keyval]
125
- key_name = tk if !tk.nil?
180
+ tk = keyval_trans[keyval]
181
+ keyname = tk if !tk.nil?
126
182
 
127
183
  key_str_parts = []
128
- key_str_parts << "ctrl" if event.state.control_mask? and key_name != "ctrl"
129
- key_str_parts << "alt" if event.state.mod1_mask? and key_name != "alt"
184
+ key_str_parts << "ctrl" if vma.kbd.modifiers[:ctrl]
185
+ key_str_parts << "alt" if vma.kbd.modifiers[:alt]
186
+ key_str_parts << "shift" if vma.kbd.modifiers[:shift]
187
+ key_str_parts << "meta" if vma.kbd.modifiers[:meta]
188
+ key_str_parts << "super" if vma.kbd.modifiers[:super]
189
+ key_str_parts << keyname
190
+
191
+ if key_str_parts[0] == key_str_parts[1]
192
+ # We don't want "ctrl-ctrl" or "alt-alt"
193
+ # TODO:There should be a better way to do this
194
+ key_str_parts.delete_at(0)
195
+ end
196
+
197
+ if key_str_parts[0] == "shift" and key_str_parts[1].class == String
198
+ #"shift-P" to just "P"
199
+ # key_str_parts.delete_at(0) if key_str_parts[1].match(/^[[:upper:]]$/)
200
+ key_str_parts.delete_at(0)
201
+ end
130
202
 
131
- key_str_parts << key_name
132
203
  key_str = key_str_parts.join("-")
133
- keynfo = { :key_str => key_str, :key_name => key_name, :keyval => event.keyval }
204
+ if key_str == "\u0000"
205
+ key_str = ""
206
+ end
207
+
208
+ keynfo = { :key_str => key_str, :key_name => keyname, :keyval => keyval }
134
209
  debug keynfo.inspect
135
210
  # $kbd.match_key_conf(key_str, nil, :key_press)
136
211
  # debug "key_str=#{key_str} key_"
137
212
 
138
213
  if key_str != "" # or prefixed_key_str != ""
139
- if sig == :key_release_event and event.keyval == @last_keyval
214
+ if sig == :key_release and keyval == @last_keyval
140
215
  $kbd.match_key_conf(key_str + "!", nil, :key_release)
141
- @last_event = [event, :key_release]
142
- elsif sig == :key_press_event
216
+ @last_event = [keynfo, :key_release]
217
+ elsif sig == :key_press
143
218
  $kbd.match_key_conf(key_str, nil, :key_press)
144
- @last_event = [event, key_str, :key_press]
219
+ @last_event = [keynfo, key_str, :key_press]
145
220
  end
146
- @last_keyval = event.keyval #TODO: outside if?
221
+ @last_keyval = keyval #TODO: outside if?
147
222
  end
148
223
 
149
224
  handle_deltas
@@ -157,7 +232,9 @@ class VSourceView < GtkSource::View
157
232
  b = buffer
158
233
  iter = b.get_iter_at(:offset => i)
159
234
  iterxy = get_iter_location(iter)
160
- winw = parent_window.width
235
+ # winw = parent_window.width #TODO:gtk4
236
+ winw = width #TODO
237
+
161
238
  view_width = visible_rect.width
162
239
  gutter_width = winw - view_width
163
240
 
@@ -167,7 +244,6 @@ class VSourceView < GtkSource::View
167
244
  # buffer_to_window_coords(Gtk::TextWindowType::TEXT, iterxy.x, iterxy.y).inspect
168
245
  # debug buffer_to_window_coords(Gtk::TextWindowType::TEXT, x, y).inspect
169
246
  (x, y) = buffer_to_window_coords(Gtk::TextWindowType::TEXT, x, y)
170
- # Ripl.start :binding => binding
171
247
 
172
248
  return [x, y]
173
249
  end
@@ -190,7 +266,8 @@ class VSourceView < GtkSource::View
190
266
  end
191
267
  end
192
268
  if any_change
193
- gui_set_cursor_pos(@bufo.id, @bufo.pos) #TODO: only when necessary
269
+ # gui_set_cursor_pos(@bufo.id, @bufo.pos) #TODO: only when necessary
270
+ self.set_cursor_pos(pos)
194
271
  end
195
272
 
196
273
  # sanity_check #TODO
@@ -236,7 +313,6 @@ class VSourceView < GtkSource::View
236
313
  # scroll_to_iter(itr, within_margin, use_align, xalign, yalign)
237
314
 
238
315
  # $view.signal_emit("extend-selection", Gtk::TextExtendSelection.new, itr,itr,itr2)
239
- # Ripl.start :binding => binding
240
316
  draw_cursor
241
317
 
242
318
  return true
@@ -251,6 +327,9 @@ class VSourceView < GtkSource::View
251
327
  # iter = buffer.get_iter_at(:offset => buffer.cursor_position)
252
328
  # iterxy = get_iter_location(iter)
253
329
 
330
+ # This is not the current buffer
331
+ return false if vma.gui.view != self
332
+
254
333
  sleep(0.01)
255
334
  # intr = iterxy.intersect(vr)
256
335
  if is_cursor_visible == false
@@ -265,8 +344,9 @@ class VSourceView < GtkSource::View
265
344
 
266
345
  scroll_to_iter(itr, within_margin, use_align, xalign, yalign)
267
346
 
268
- # return true # Call this func again
347
+ return true # Call this func again
269
348
  else
349
+ @idle_func_running = false
270
350
  return false # Don't call this idle func again
271
351
  end
272
352
  end
@@ -282,9 +362,6 @@ class VSourceView < GtkSource::View
282
362
  if intr.nil?
283
363
  debug iterxy.inspect
284
364
  debug vr.inspect
285
- # Ripl.start :binding => binding
286
-
287
- # exit!
288
365
  return false
289
366
  else
290
367
  return true
@@ -292,7 +369,12 @@ class VSourceView < GtkSource::View
292
369
  end
293
370
 
294
371
  def ensure_cursor_visible
372
+ return #TODO:gtk4
373
+ debug "@idle_func_running=#{@idle_func_running}"
374
+ return if @idle_func_running
295
375
  if is_cursor_visible == false
376
+ @idle_func_running = true
377
+ debug "Starting idle func"
296
378
  Thread.new {
297
379
  sleep 0.01
298
380
  GLib::Idle.add(proc { cursor_visible_idle_func })
@@ -301,21 +383,33 @@ class VSourceView < GtkSource::View
301
383
  end
302
384
 
303
385
  def draw_cursor
304
- if is_command_mode
386
+ mode = vma.kbd.get_mode
387
+ ctype = vma.kbd.get_cursor_type
388
+ # if is_command_mode
389
+ if ctype == :command
305
390
  itr = buffer.get_iter_at(:offset => @bufo.pos)
306
391
  itr2 = buffer.get_iter_at(:offset => @bufo.pos + 1)
307
- $view.buffer.select_range(itr, itr2)
308
- elsif @bufo.visual_mode?
392
+ buffer.select_range(itr, itr2)
393
+ # elsif @bufo.visual_mode?
394
+ elsif ctype == :visual
309
395
  debug "VISUAL MODE"
310
396
  (_start, _end) = @bufo.get_visual_mode_range2
311
397
  debug "#{_start}, #{_end}"
312
398
  itr = buffer.get_iter_at(:offset => _start)
313
399
  itr2 = buffer.get_iter_at(:offset => _end + 1)
314
- $view.buffer.select_range(itr, itr2)
315
- else # Insert mode
400
+ # Pango-CRITICAL **: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
401
+ buffer.select_range(itr, itr2)
402
+ elsif ctype == :insert
403
+ # Not sure why this is needed
316
404
  itr = buffer.get_iter_at(:offset => @bufo.pos)
317
- $view.buffer.select_range(itr, itr)
405
+ buffer.select_range(itr, itr)
406
+
407
+ # Via trial and error, this combination is only thing that seems to work:
408
+ vma.gui.sw.child.toggle_cursor_visible
409
+ vma.gui.sw.child.cursor_visible = true
410
+
318
411
  debug "INSERT MODE"
412
+ else # TODO
319
413
  end
320
414
  end
321
415
  end