@@ -48,7 +48,15 @@ typedef struct ui_dirty_layer {
4848 int dirty ;
4949} ui_dirty_layer_t ;
5050
51+ typedef enum {
52+ UI_CONNECTION_STATE_PENDING ,
53+ UI_CONNECTION_STATE_INITIALIZING ,
54+ UI_CONNECTION_STATE_INITIALIZED ,
55+ } ui_connection_state_t ;
56+
5157typedef struct ui_connection {
58+ ui_connection_state_t state ;
59+
5260 /** whether new content has been rendered */
5361 bool rendered ;
5462
@@ -173,7 +181,7 @@ static void ui_server_on_window_visibility_change(ptk_event_t *e, void *arg)
173181 ui_connection_t * conn ;
174182
175183 conn = ui_server_find_connection (NULL , e -> window );
176- if (conn ) {
184+ if (conn && conn -> state == UI_CONNECTION_STATE_INITIALIZED ) {
177185 conn -> window_visible = e -> visibility_change .visible ;
178186 if (conn -> window_visible ) {
179187 ui_widget_show (conn -> widget );
@@ -208,10 +216,9 @@ static void ui_server_on_window_resize(ptk_event_t *e, void *arg)
208216 float scale , width , height ;
209217
210218 conn = ui_server_find_connection (NULL, e -> window );
211- if (!conn ) {
219+ if (!conn || conn -> state != UI_CONNECTION_STATE_INITIALIZED ) {
212220 return ;
213221 }
214-
215222 scale = css_metrics_actual_scale (& conn -> updater -> metrics );
216223 width = e -> size .width / scale ;
217224 height = e -> size .height / scale ;
@@ -289,44 +296,24 @@ static void ui_server_on_destroy_widget(ui_widget_t *widget, ui_event_t *e,
289296static void ui_server_refresh_window (ui_connection_t * conn )
290297{
291298 pd_rect_t rect ;
299+ float scale = css_metrics_actual_scale (& conn -> updater -> metrics );
292300
293301 ui_widget_mark_dirty_rect (conn -> widget , NULL , UI_BOX_TYPE_GRAPH_BOX );
294302 ui_compute_rect (& rect , & conn -> widget -> canvas_box );
295303 ptk_window_set_title (conn -> window , conn -> widget -> title );
296- ptk_window_set_size (conn -> window , rect .width , rect .height );
297304 if (conn -> widget -> computed_style .type_bits .top == CSS_TOP_AUTO ) {
298- rect .y = (ptk_screen_get_height () - rect .height ) / 2 ;
305+ rect .y =
306+ (int )((ptk_screen_get_height () - rect .height * scale ) / 2 );
299307 }
300308 if (conn -> widget -> computed_style .type_bits .left == CSS_LEFT_AUTO ) {
301- rect .x = (ptk_screen_get_width () - rect .width ) / 2 ;
309+ rect .x =
310+ (int )((ptk_screen_get_width () - rect .width * scale ) / 2 );
302311 }
312+ ptk_window_set_size (conn -> window , rect .width , rect .height );
303313 ptk_window_set_position (conn -> window , rect .x , rect .y );
304- conn -> window_visible = ui_widget_is_visible (conn -> widget );
305- if (conn -> window_visible ) {
306- ptk_window_show (conn -> window );
307- } else {
308- ptk_window_hide (conn -> window );
309- }
310314 ptk_window_activate (conn -> window );
311315}
312316
313- static void ui_server_on_widget_ready (ui_widget_t * w , ui_event_t * e , void * arg )
314- {
315- list_node_t * node ;
316- ui_connection_t * conn ;
317-
318- // 考虑到连接可能会在组件 ready 事件之前被销毁,
319- // 所以从连接列表中查找以确认连接是否存在
320- for (list_each (node , & ui_server .connections )) {
321- conn = node -> data ;
322- if (conn || conn -> widget == w ) {
323- ui_server_refresh_window (conn );
324- logger_debug ("[ui-server] [window %p] refresh\n" ,
325- conn -> window );
326- }
327- }
328- }
329-
330317void ui_server_connect (ui_widget_t * widget , ptk_window_t * window )
331318{
332319 ui_event_t e = { 0 };
@@ -337,20 +324,16 @@ void ui_server_connect(ui_widget_t *widget, ptk_window_t *window)
337324 conn -> window = window ;
338325 conn -> widget = widget ;
339326 conn -> rendered = false;
340- conn -> window_visible = false;
341327 conn -> updater = ui_updater_create ();
342328 conn -> updater -> metrics .dpi = 1.f * ptk_window_get_dpi (window );
329+ conn -> state = UI_CONNECTION_STATE_PENDING ;
330+ conn -> window_visible = ui_widget_is_visible (widget );
343331 options .properties = true;
344332 list_create (& conn -> flash_rects );
345333 list_append (& ui_server .connections , conn );
346334 ui_widget_on (widget , "destroy" , ui_server_on_destroy_widget , NULL );
347335 ui_mutation_observer_observe (ui_server .observer , widget , options );
348- ui_widget_on (widget , "ready" , ui_server_on_widget_ready , NULL );
349- if (widget -> state == UI_WIDGET_STATE_NORMAL ) {
350- e .type = UI_EVENT_READY ;
351- e .target = widget ;
352- ui_post_event (& e , NULL , NULL );
353- }
336+ // 在同步前处理所有消息,包括窗口位置、大小变更消息,避免在初次更新时组件的位置和尺寸被窗口覆盖
354337 ptk_process_native_events (PTK_PROCESS_EVENTS_ALL_IF_PRESENT );
355338 logger_debug ("[ui-server] [window %p] connect widget(%p, %s)\n" , window ,
356339 widget , widget -> type );
@@ -609,13 +592,15 @@ static int window_mutation_list_add(list_t *list,
609592{
610593 list_node_t * node ;
611594 ptk_window_t * wnd ;
595+ ui_connection_t * conn ;
612596 ui_widget_t * widget = mutation -> target ;
613597 window_mutation_record_t * wnd_mutation = NULL ;
614598
615- wnd = ui_server_get_window (widget );
616- if (!wnd ) {
599+ conn = ui_server_find_connection (widget , NULL );
600+ if (!conn || conn -> state != UI_CONNECTION_STATE_INITIALIZED ) {
617601 return -1 ;
618602 }
603+ wnd = conn -> window ;
619604 for (list_each (node , list )) {
620605 wnd_mutation = node -> data ;
621606 if (wnd_mutation -> window == wnd ) {
@@ -725,6 +710,11 @@ void ui_server_update(void)
725710 conn = node -> data ;
726711 ui_metrics .dpi = 1.f * ptk_window_get_dpi (conn -> window );
727712 ui_updater_update (conn -> updater , conn -> widget );
713+ if (conn -> state == UI_CONNECTION_STATE_PENDING ) {
714+ conn -> state = UI_CONNECTION_STATE_INITIALIZING ;
715+ ui_server_refresh_window (conn );
716+ conn -> state = UI_CONNECTION_STATE_INITIALIZED ;
717+ }
728718 }
729719 } else {
730720 ui_update ();
0 commit comments