@@ -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,68 +296,43 @@ 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{
332- ui_event_t e = { 0 };
333319 ui_connection_t * conn ;
334320 ui_mutation_observer_init_t options = { 0 };
335321
336322 conn = malloc (sizeof (ui_connection_t ));
337323 conn -> window = window ;
338324 conn -> widget = widget ;
339325 conn -> rendered = false;
340- conn -> window_visible = false;
341326 conn -> updater = ui_updater_create ();
342327 conn -> updater -> metrics .dpi = 1.f * ptk_window_get_dpi (window );
328+ conn -> state = UI_CONNECTION_STATE_PENDING ;
329+ conn -> window_visible = ui_widget_is_visible (widget );
343330 options .properties = true;
344331 list_create (& conn -> flash_rects );
345332 list_append (& ui_server .connections , conn );
346333 ui_widget_on (widget , "destroy" , ui_server_on_destroy_widget , NULL );
347334 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- }
335+ // 在同步前处理所有消息,包括窗口位置、大小变更消息,避免在初次更新时组件的位置和尺寸被窗口覆盖
354336 ptk_process_native_events (PTK_PROCESS_EVENTS_ALL_IF_PRESENT );
355337 logger_debug ("[ui-server] [window %p] connect widget(%p, %s)\n" , window ,
356338 widget , widget -> type );
@@ -609,13 +591,15 @@ static int window_mutation_list_add(list_t *list,
609591{
610592 list_node_t * node ;
611593 ptk_window_t * wnd ;
594+ ui_connection_t * conn ;
612595 ui_widget_t * widget = mutation -> target ;
613596 window_mutation_record_t * wnd_mutation = NULL ;
614597
615- wnd = ui_server_get_window (widget );
616- if (!wnd ) {
598+ conn = ui_server_find_connection (widget , NULL );
599+ if (!conn || conn -> state != UI_CONNECTION_STATE_INITIALIZED ) {
617600 return -1 ;
618601 }
602+ wnd = conn -> window ;
619603 for (list_each (node , list )) {
620604 wnd_mutation = node -> data ;
621605 if (wnd_mutation -> window == wnd ) {
@@ -725,6 +709,11 @@ void ui_server_update(void)
725709 conn = node -> data ;
726710 ui_metrics .dpi = 1.f * ptk_window_get_dpi (conn -> window );
727711 ui_updater_update (conn -> updater , conn -> widget );
712+ if (conn -> state == UI_CONNECTION_STATE_PENDING ) {
713+ conn -> state = UI_CONNECTION_STATE_INITIALIZING ;
714+ ui_server_refresh_window (conn );
715+ conn -> state = UI_CONNECTION_STATE_INITIALIZED ;
716+ }
728717 }
729718 } else {
730719 ui_update ();
0 commit comments