44import sys
55
66from functools import partial
7+ from types import SimpleNamespace
78
89import cairo
910
@@ -99,14 +100,29 @@ def __init__(self, font):
99100 self .grids = {}
100101 self .g = None
101102
102- def create_drawing_area (self , handle ):
103+ def get_grid (self , handle ):
104+ if handle in self .grids :
105+ return self .grids [handle ]
103106 g = Grid ()
104107 g .handle = handle
105- g ._resize_timer_id = None
108+ g ._pending = [0 , 0 , 0 ]
109+ g ._screen = None
106110 drawing_area = Gtk .DrawingArea ()
107111 drawing_area .connect ('draw' , partial (self ._gtk_draw , g ))
112+ g ._pango_context = drawing_area .create_pango_context ()
113+ g ._drawing_area = drawing_area
114+ g ._window = None
115+ g .options = None
116+ self .grids [handle ] = g
117+ return g
118+
119+ def create_window (self , handle ):
120+ g = self .get_grid (handle )
121+ g ._resize_timer_id = None
108122 window = Gtk .Window ()
109- window .add (drawing_area )
123+ layout = Gtk .Fixed ()
124+ window .add (layout )
125+ layout .put (g ._drawing_area ,0 ,0 )
110126 window .set_events (window .get_events () |
111127 Gdk .EventMask .BUTTON_PRESS_MASK |
112128 Gdk .EventMask .BUTTON_RELEASE_MASK |
@@ -123,14 +139,9 @@ def create_drawing_area(self, handle):
123139 window .connect ('focus-in-event' , self ._gtk_focus_in )
124140 window .connect ('focus-out-event' , self ._gtk_focus_out )
125141 window .show_all ()
126- g ._pango_context = drawing_area .create_pango_context ()
127- g ._drawing_area = drawing_area
128142 g ._window = window
129- g ._pending = [0 , 0 , 0 ]
130- g ._screen = None
143+ g ._layout = layout
131144
132- self .grids [handle ] = g
133- return g
134145
135146
136147 def start (self , bridge ):
@@ -145,8 +156,10 @@ def start(self, bridge):
145156 im_context .set_use_preedit (False ) # TODO: preedit at cursor position
146157 im_context .connect ('commit' , self ._gtk_input )
147158 self ._im_context = im_context
148- self .g = self .create_drawing_area (1 )
159+ self .create_window (1 )
160+ self .g = self .get_grid (1 )
149161 self ._window = self .g ._window
162+ self ._layout = self .g ._layout
150163 self ._bridge = bridge
151164 Gtk .main ()
152165
@@ -165,19 +178,60 @@ def wrapper():
165178 GObject .idle_add (wrapper )
166179
167180 def _nvim_grid_cursor_goto (self , grid , row , col ):
168- g = self .grids [ grid ]
181+ g = self .get_grid ( grid )
169182 self .g = g
170183 if g ._screen is not None :
171184 # TODO: this should really be asserted on the nvim side
172185 row , col = min (row , g ._screen .rows - 1 ), min (col , g ._screen .columns - 1 )
173186 g ._screen .cursor_goto (row ,col )
174187 self ._window = self .g ._window
188+ self ._screen = self .g ._screen
189+
190+ def _nvim_float_info (self , win , handle , width , height , options ):
191+ g = self .get_grid (handle )
192+ g .nvim_win = win
193+ g .options = SimpleNamespace (** options )
194+ self .configure_float (g )
195+
196+ def _nvim_float_close (self , win , handle ):
197+ g = self .get_grid (handle )
198+
199+ if g ._window is not None :
200+ g ._layout .remove (g ._drawing_area )
201+ g ._window .destroy ()
202+ elif g ._drawing_area .get_parent () == self ._layout :
203+ self ._layout .remove (g ._drawing_area )
204+
205+ def configure_float (self , g ):
206+ if g .options .standalone :
207+ if not g ._window :
208+ if g ._drawing_area .get_parent () == self ._layout :
209+ self ._layout .remove (g ._drawing_area )
210+ self .create_window (g .handle )
211+ else :
212+ if g ._window is not None :
213+ g ._layout .remove (g ._drawing_area )
214+ g ._window .destroy ()
215+ # this is ugly, but I'm too lazy to refactor nvim_resize
216+ # to fit the flow of information
217+ if g ._drawing_area .get_parent () != self ._layout :
218+ self ._layout .add (g ._drawing_area )
219+ g ._drawing_area .show ()
220+ if g ._screen is not None :
221+ x = g .options .x * self ._cell_pixel_width
222+ y = g .options .y * self ._cell_pixel_height
223+ w ,h = g .pixel_size
224+ if len (g .options .anchor ) >= 2 :
225+ if g .options .anchor [0 ] == 'S' :
226+ y -= h
227+ if g .options .anchor [1 ] == 'E' :
228+ x -= w
229+ self ._layout .move (g ._drawing_area ,x ,y )
230+
175231
176232 def _nvim_grid_resize (self , grid , columns , rows ):
177233 print ("da" )
178- if grid not in self .grids :
179- self .create_drawing_area (grid )
180- g = self .grids [grid ]
234+ g = self .get_grid (grid )
181235 da = g ._drawing_area
182236 # create FontDescription object for the selected font/size
183237 font_str = '{0} {1}' .format (self ._font_name , self ._font_size )
@@ -202,7 +256,13 @@ def _nvim_grid_resize(self, grid, columns, rows):
202256 self ._cell_pixel_width = cell_pixel_width
203257 self ._cell_pixel_height = cell_pixel_height
204258 g ._screen = Screen (columns , rows )
205- g ._window .resize (pixel_width , pixel_height )
259+ g ._drawing_area .set_size_request (pixel_width , pixel_height )
260+ g .pixel_size = pixel_width , pixel_height
261+ if g .options is not None :
262+ self .configure_float (g )
263+
264+ if g ._window is not None :
265+ g ._window .resize (pixel_width , pixel_height )
206266
207267 def _nvim_grid_clear (self , grid ):
208268 g = self .grids [grid ]
0 commit comments