55import sys
66
77from functools import partial
8+ from types import SimpleNamespace
89
910import cairo
1011
@@ -100,14 +101,29 @@ def __init__(self, font):
100101 self .grids = {}
101102 self .g = None
102103
103- def create_drawing_area (self , handle ):
104+ def get_grid (self , handle ):
105+ if handle in self .grids :
106+ return self .grids [handle ]
104107 g = Grid ()
105108 g .handle = handle
106- g ._resize_timer_id = None
109+ g ._pending = [0 , 0 , 0 ]
110+ g ._screen = None
107111 drawing_area = Gtk .DrawingArea ()
108112 drawing_area .connect ('draw' , partial (self ._gtk_draw , g ))
113+ g ._pango_context = drawing_area .create_pango_context ()
114+ g ._drawing_area = drawing_area
115+ g ._window = None
116+ g .options = None
117+ self .grids [handle ] = g
118+ return g
119+
120+ def create_window (self , handle ):
121+ g = self .get_grid (handle )
122+ g ._resize_timer_id = None
109123 window = Gtk .Window ()
110- window .add (drawing_area )
124+ layout = Gtk .Fixed ()
125+ window .add (layout )
126+ layout .put (g ._drawing_area ,0 ,0 )
111127 window .set_events (window .get_events () |
112128 Gdk .EventMask .BUTTON_PRESS_MASK |
113129 Gdk .EventMask .BUTTON_RELEASE_MASK |
@@ -124,14 +140,9 @@ def create_drawing_area(self, handle):
124140 window .connect ('focus-in-event' , self ._gtk_focus_in )
125141 window .connect ('focus-out-event' , self ._gtk_focus_out )
126142 window .show_all ()
127- g ._pango_context = drawing_area .create_pango_context ()
128- g ._drawing_area = drawing_area
129143 g ._window = window
130- g ._pending = [0 , 0 , 0 ]
131- g ._screen = None
144+ g ._layout = layout
132145
133- self .grids [handle ] = g
134- return g
135146
136147
137148 def start (self , bridge ):
@@ -148,8 +159,10 @@ def start(self, bridge):
148159 im_context .set_use_preedit (False ) # TODO: preedit at cursor position
149160 im_context .connect ('commit' , self ._gtk_input )
150161 self ._im_context = im_context
151- self .g = self .create_drawing_area (1 )
162+ self .create_window (1 )
163+ self .g = self .get_grid (1 )
152164 self ._window = self .g ._window
165+ self ._layout = self .g ._layout
153166 self ._bridge = bridge
154167 Gtk .main ()
155168
@@ -168,19 +181,60 @@ def wrapper():
168181 GObject .idle_add (wrapper )
169182
170183 def _nvim_grid_cursor_goto (self , grid , row , col ):
171- g = self .grids [ grid ]
184+ g = self .get_grid ( grid )
172185 self .g = g
173186 if g ._screen is not None :
174187 # TODO: this should really be asserted on the nvim side
175188 row , col = min (row , g ._screen .rows - 1 ), min (col , g ._screen .columns - 1 )
176189 g ._screen .cursor_goto (row ,col )
177190 self ._window = self .g ._window
191+ self ._screen = self .g ._screen
192+
193+ def _nvim_float_info (self , win , handle , width , height , options ):
194+ g = self .get_grid (handle )
195+ g .nvim_win = win
196+ g .options = SimpleNamespace (** options )
197+ self .configure_float (g )
198+
199+ def _nvim_float_close (self , win , handle ):
200+ g = self .get_grid (handle )
201+
202+ if g ._window is not None :
203+ g ._layout .remove (g ._drawing_area )
204+ g ._window .destroy ()
205+ elif g ._drawing_area .get_parent () == self ._layout :
206+ self ._layout .remove (g ._drawing_area )
207+
208+ def configure_float (self , g ):
209+ if g .options .standalone :
210+ if not g ._window :
211+ if g ._drawing_area .get_parent () == self ._layout :
212+ self ._layout .remove (g ._drawing_area )
213+ self .create_window (g .handle )
214+ else :
215+ if g ._window is not None :
216+ g ._layout .remove (g ._drawing_area )
217+ g ._window .destroy ()
218+ # this is ugly, but I'm too lazy to refactor nvim_resize
219+ # to fit the flow of information
220+ if g ._drawing_area .get_parent () != self ._layout :
221+ self ._layout .add (g ._drawing_area )
222+ g ._drawing_area .show ()
223+ if g ._screen is not None :
224+ x = g .options .x * self ._cell_pixel_width
225+ y = g .options .y * self ._cell_pixel_height
226+ w ,h = g .pixel_size
227+ if len (g .options .anchor ) >= 2 :
228+ if g .options .anchor [0 ] == 'S' :
229+ y -= h
230+ if g .options .anchor [1 ] == 'E' :
231+ x -= w
232+ self ._layout .move (g ._drawing_area ,x ,y )
233+
178234
179235 def _nvim_grid_resize (self , grid , columns , rows ):
180236 print ("da" )
181- if grid not in self .grids :
182- self .create_drawing_area (grid )
183- g = self .grids [grid ]
237+ g = self .get_grid (grid )
184238 da = g ._drawing_area
185239 # create FontDescription object for the selected font/size
186240 font_str = '{0} {1}' .format (self ._font_name , self ._font_size )
@@ -205,7 +259,13 @@ def _nvim_grid_resize(self, grid, columns, rows):
205259 self ._cell_pixel_width = cell_pixel_width
206260 self ._cell_pixel_height = cell_pixel_height
207261 g ._screen = Screen (columns , rows )
208- g ._window .resize (pixel_width , pixel_height )
262+ g ._drawing_area .set_size_request (pixel_width , pixel_height )
263+ g .pixel_size = pixel_width , pixel_height
264+ if g .options is not None :
265+ self .configure_float (g )
266+
267+ if g ._window is not None :
268+ g ._window .resize (pixel_width , pixel_height )
209269
210270 def _nvim_grid_clear (self , grid ):
211271 g = self .grids [grid ]
0 commit comments