diff options
| author | Yuuki Harano | 2020-09-06 23:27:45 +0900 |
|---|---|---|
| committer | Jeff Walsh | 2020-11-24 12:24:40 +1100 |
| commit | 28073ba59bbabec1194977d654b471800ce63f45 (patch) | |
| tree | 967c439b8f95894da3e573b0897d28b3b4d6c6d2 /src/pgtkterm.c | |
| parent | e75ce0302d4c907c8ff56fb15fc7dd12b48e7370 (diff) | |
| download | emacs-28073ba59bbabec1194977d654b471800ce63f45.tar.gz emacs-28073ba59bbabec1194977d654b471800ce63f45.zip | |
Re-implement childframe with emacsgtkfixed
* src/emacsgtkfixed.c (G_DEFINE_TYPE): Make emacs_fixed_get_type public.
* src/emacsgtkfixed.h (EMACS_TYPE_FIXED): Make emacs_fixed_get_type public.
* src/gtkutil.c (xg_frame_set_char_size): Call appropriate functions
by whether the frame is a child frame or not.
(xg_create_frame_widgets): Use GTK_WINDOW_TOPLEVEL when creating child frame.
(xg_create_frame_outer_widgets): New function.
(xg_set_skip_taskbar): Call only when top-level frame.
(xg_set_no_accept_focus): See appropriate widget.
* src/gtkutil.h: New declaration.
* src/pgtkfns.c (pgtk_set_name_internal): Do only when top-level frame.
(Fx_create_frame): Reparent the frame.
(frame_geometry): Call appropriate functions
(syms_of_pgtkfns): Port from X code.
* src/pgtkterm.c (x_free_frame_resources): Destroy appropriate widget.
(x_calc_absolute_position): Port from X code.
(x_set_offset): Re-port from X code.
(pgtk_set_window_size): Use appropriate widget.
(pgtk_make_frame_visible): Use appropriate widget.
(pgtk_make_frame_invisible): Use appropriate widget.
(x_set_parent_frame): Reparent the frame.
(x_set_z_group): Process only when top-level frame.
(pgtk_text_icon): Process only when top-level frame.
(set_fullscreen_state): Process only when top-level frame.
(frame_highlight): Hold ref.
(frame_unhighlight): Hold ref.
(pgtk_window_is_of_frame_recursive): Prune child frames.
(pgtk_window_is_of_frame): Prune child frames.
(print_widget_tree_recursive): Don't call this when not debugging.
(pgtk_handle_draw): Don't call this when not debugging.
(pgtk_set_event_handler): expect map-event for edit_widget not outer widget.
* src/pgtkterm.h (FRAME_WIDGET): New macro.
Diffstat (limited to 'src/pgtkterm.c')
| -rw-r--r-- | src/pgtkterm.c | 307 |
1 files changed, 242 insertions, 65 deletions
diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 6d8b1ece877..d62e2a3b16d 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c | |||
| @@ -60,6 +60,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 60 | #include "font.h" | 60 | #include "font.h" |
| 61 | #include "xsettings.h" | 61 | #include "xsettings.h" |
| 62 | #include "pgtkselect.h" | 62 | #include "pgtkselect.h" |
| 63 | #include "emacsgtkfixed.h" | ||
| 63 | 64 | ||
| 64 | #define STORE_KEYSYM_FOR_DEBUG(keysym) ((void)0) | 65 | #define STORE_KEYSYM_FOR_DEBUG(keysym) ((void)0) |
| 65 | 66 | ||
| @@ -227,10 +228,10 @@ x_free_frame_resources (struct frame *f) | |||
| 227 | 228 | ||
| 228 | if (FRAME_X_OUTPUT (f)->border_color_css_provider != NULL) | 229 | if (FRAME_X_OUTPUT (f)->border_color_css_provider != NULL) |
| 229 | { | 230 | { |
| 230 | GtkStyleContext *ctxt = | 231 | GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f)); |
| 231 | gtk_widget_get_style_context (FRAME_GTK_OUTER_WIDGET (f)); | ||
| 232 | GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider; | 232 | GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider; |
| 233 | gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old)); | 233 | gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old)); |
| 234 | g_object_unref (old); | ||
| 234 | FRAME_X_OUTPUT (f)->border_color_css_provider = NULL; | 235 | FRAME_X_OUTPUT (f)->border_color_css_provider = NULL; |
| 235 | } | 236 | } |
| 236 | 237 | ||
| @@ -250,7 +251,7 @@ x_free_frame_resources (struct frame *f) | |||
| 250 | FRAME_X_OUTPUT (f)->scrollbar_background_css_provider = NULL; | 251 | FRAME_X_OUTPUT (f)->scrollbar_background_css_provider = NULL; |
| 251 | } | 252 | } |
| 252 | 253 | ||
| 253 | gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f)); | 254 | gtk_widget_destroy (FRAME_WIDGET (f)); |
| 254 | 255 | ||
| 255 | if (FRAME_X_OUTPUT (f)->cr_surface_visible_bell != NULL) | 256 | if (FRAME_X_OUTPUT (f)->cr_surface_visible_bell != NULL) |
| 256 | { | 257 | { |
| @@ -286,6 +287,80 @@ x_destroy_window (struct frame *f) | |||
| 286 | dpyinfo->reference_count--; | 287 | dpyinfo->reference_count--; |
| 287 | } | 288 | } |
| 288 | 289 | ||
| 290 | /* Calculate the absolute position in frame F | ||
| 291 | from its current recorded position values and gravity. */ | ||
| 292 | |||
| 293 | static void | ||
| 294 | x_calc_absolute_position (struct frame *f) | ||
| 295 | { | ||
| 296 | int flags = f->size_hint_flags; | ||
| 297 | struct frame *p = FRAME_PARENT_FRAME (f); | ||
| 298 | |||
| 299 | /* We have nothing to do if the current position | ||
| 300 | is already for the top-left corner. */ | ||
| 301 | if (! ((flags & XNegative) || (flags & YNegative))) | ||
| 302 | return; | ||
| 303 | |||
| 304 | /* Treat negative positions as relative to the leftmost bottommost | ||
| 305 | position that fits on the screen. */ | ||
| 306 | if ((flags & XNegative) && (f->left_pos <= 0)) | ||
| 307 | { | ||
| 308 | int width = FRAME_PIXEL_WIDTH (f); | ||
| 309 | |||
| 310 | /* A frame that has been visible at least once should have outer | ||
| 311 | edges. */ | ||
| 312 | if (f->output_data.pgtk->has_been_visible && !p) | ||
| 313 | { | ||
| 314 | Lisp_Object frame; | ||
| 315 | Lisp_Object edges = Qnil; | ||
| 316 | |||
| 317 | XSETFRAME (frame, f); | ||
| 318 | edges = Fpgtk_frame_edges (frame, Qouter_edges); | ||
| 319 | if (!NILP (edges)) | ||
| 320 | width = (XFIXNUM (Fnth (make_fixnum (2), edges)) | ||
| 321 | - XFIXNUM (Fnth (make_fixnum (0), edges))); | ||
| 322 | } | ||
| 323 | |||
| 324 | if (p) | ||
| 325 | f->left_pos = (FRAME_PIXEL_WIDTH (p) - width - 2 * f->border_width | ||
| 326 | + f->left_pos); | ||
| 327 | else | ||
| 328 | f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f)) | ||
| 329 | - width + f->left_pos); | ||
| 330 | |||
| 331 | } | ||
| 332 | |||
| 333 | if ((flags & YNegative) && (f->top_pos <= 0)) | ||
| 334 | { | ||
| 335 | int height = FRAME_PIXEL_HEIGHT (f); | ||
| 336 | |||
| 337 | if (f->output_data.pgtk->has_been_visible && !p) | ||
| 338 | { | ||
| 339 | Lisp_Object frame; | ||
| 340 | Lisp_Object edges = Qnil; | ||
| 341 | |||
| 342 | XSETFRAME (frame, f); | ||
| 343 | if (NILP (edges)) | ||
| 344 | edges = Fpgtk_frame_edges (frame, Qouter_edges); | ||
| 345 | if (!NILP (edges)) | ||
| 346 | height = (XFIXNUM (Fnth (make_fixnum (3), edges)) | ||
| 347 | - XFIXNUM (Fnth (make_fixnum (1), edges))); | ||
| 348 | } | ||
| 349 | |||
| 350 | if (p) | ||
| 351 | f->top_pos = (FRAME_PIXEL_HEIGHT (p) - height - 2 * f->border_width | ||
| 352 | + f->top_pos); | ||
| 353 | else | ||
| 354 | f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f)) | ||
| 355 | - height + f->top_pos); | ||
| 356 | } | ||
| 357 | |||
| 358 | /* The left_pos and top_pos | ||
| 359 | are now relative to the top and left screen edges, | ||
| 360 | so the flags should correspond. */ | ||
| 361 | f->size_hint_flags &= ~ (XNegative | YNegative); | ||
| 362 | } | ||
| 363 | |||
| 289 | /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position, | 364 | /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position, |
| 290 | to really change the position, and 0 when calling from | 365 | to really change the position, and 0 when calling from |
| 291 | x_make_frame_visible (in that case, XOFF and YOFF are the current | 366 | x_make_frame_visible (in that case, XOFF and YOFF are the current |
| @@ -300,48 +375,60 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_gravity) | |||
| 300 | { | 375 | { |
| 301 | PGTK_TRACE ("x_set_offset: %d,%d,%d.", xoff, yoff, change_gravity); | 376 | PGTK_TRACE ("x_set_offset: %d,%d,%d.", xoff, yoff, change_gravity); |
| 302 | 377 | ||
| 303 | struct frame *parent = FRAME_PARENT_FRAME (f); | 378 | int modified_top, modified_left; |
| 304 | GtkAllocation a = { 0 }; | ||
| 305 | int surface_pos_x = 0; | ||
| 306 | int surface_pos_y = 0; | ||
| 307 | |||
| 308 | if (parent) | ||
| 309 | { | ||
| 310 | /* determing the "height" of the titlebar, by finding the | ||
| 311 | location of the "emacsfixed" widget on the surface/window */ | ||
| 312 | GtkWidget *w = FRAME_GTK_WIDGET (parent); | ||
| 313 | gtk_widget_get_allocation (w, &a); | ||
| 314 | } | ||
| 315 | 379 | ||
| 316 | if (change_gravity > 0) | 380 | if (change_gravity > 0) |
| 317 | { | 381 | { |
| 318 | f->size_hint_flags &= ~(XNegative | YNegative); | ||
| 319 | f->left_pos = xoff; | ||
| 320 | f->top_pos = yoff; | 382 | f->top_pos = yoff; |
| 321 | 383 | f->left_pos = xoff; | |
| 384 | f->size_hint_flags &= ~ (XNegative | YNegative); | ||
| 322 | if (xoff < 0) | 385 | if (xoff < 0) |
| 323 | { | 386 | f->size_hint_flags |= XNegative; |
| 324 | f->size_hint_flags |= XNegative; | ||
| 325 | } | ||
| 326 | if (yoff < 0) | 387 | if (yoff < 0) |
| 327 | { | 388 | f->size_hint_flags |= YNegative; |
| 328 | f->size_hint_flags |= YNegative; | ||
| 329 | } | ||
| 330 | f->win_gravity = NorthWestGravity; | 389 | f->win_gravity = NorthWestGravity; |
| 331 | } | 390 | } |
| 332 | 391 | ||
| 392 | x_calc_absolute_position (f); | ||
| 393 | |||
| 333 | block_input (); | 394 | block_input (); |
| 334 | surface_pos_y = f->top_pos + a.y; | 395 | x_wm_set_size_hint (f, 0, false); |
| 335 | surface_pos_x = f->left_pos + a.x; | ||
| 336 | 396 | ||
| 337 | /* When a position change was requested and the outer GTK widget | 397 | if (x_gtk_use_window_move) |
| 338 | has been realized already, leave it to gtk_window_move to DTRT | 398 | { |
| 339 | and return. Used for Bug#25851 and Bug#25943. */ | 399 | if (change_gravity != 0) |
| 340 | if (change_gravity != 0 && FRAME_GTK_OUTER_WIDGET (f)) | 400 | { |
| 401 | if (FRAME_GTK_OUTER_WIDGET (f)) | ||
| 402 | { | ||
| 403 | gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), | ||
| 404 | f->left_pos, f->top_pos); | ||
| 405 | } | ||
| 406 | else | ||
| 407 | { | ||
| 408 | GtkWidget *fixed = FRAME_GTK_WIDGET (f); | ||
| 409 | GtkWidget *parent = gtk_widget_get_parent (fixed); | ||
| 410 | gtk_fixed_move (GTK_FIXED (parent), fixed, | ||
| 411 | f->left_pos, f->top_pos); | ||
| 412 | } | ||
| 413 | } | ||
| 414 | unblock_input (); | ||
| 415 | return; | ||
| 416 | } | ||
| 417 | |||
| 418 | modified_left = f->left_pos; | ||
| 419 | modified_top = f->top_pos; | ||
| 420 | |||
| 421 | if (FRAME_GTK_OUTER_WIDGET (f)) | ||
| 341 | { | 422 | { |
| 342 | PGTK_TRACE ("x_set_offset: move to %d,%d.", surface_pos_x, surface_pos_y); | ||
| 343 | gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), | 423 | gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), |
| 344 | surface_pos_x, surface_pos_y); | 424 | modified_left, modified_top); |
| 425 | } | ||
| 426 | else | ||
| 427 | { | ||
| 428 | GtkWidget *fixed = FRAME_GTK_WIDGET (f); | ||
| 429 | GtkWidget *parent = gtk_widget_get_parent (fixed); | ||
| 430 | gtk_fixed_move (GTK_FIXED (parent), fixed, | ||
| 431 | modified_left, modified_top); | ||
| 345 | } | 432 | } |
| 346 | 433 | ||
| 347 | unblock_input (); | 434 | unblock_input (); |
| @@ -397,7 +484,7 @@ pgtk_set_window_size (struct frame *f, | |||
| 397 | x_wm_set_size_hint (f, 0, 0); | 484 | x_wm_set_size_hint (f, 0, 0); |
| 398 | xg_frame_set_char_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth), | 485 | xg_frame_set_char_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth), |
| 399 | FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight)); | 486 | FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight)); |
| 400 | gtk_widget_queue_resize (FRAME_GTK_OUTER_WIDGET (f)); | 487 | gtk_widget_queue_resize (FRAME_WIDGET (f)); |
| 401 | 488 | ||
| 402 | unblock_input (); | 489 | unblock_input (); |
| 403 | } | 490 | } |
| @@ -488,8 +575,9 @@ pgtk_make_frame_visible (struct frame *f) | |||
| 488 | 575 | ||
| 489 | if (!FRAME_VISIBLE_P (f)) | 576 | if (!FRAME_VISIBLE_P (f)) |
| 490 | { | 577 | { |
| 491 | gtk_widget_show (win); | 578 | gtk_widget_show (FRAME_WIDGET (f)); |
| 492 | gtk_window_deiconify (GTK_WINDOW (win)); | 579 | if (win) |
| 580 | gtk_window_deiconify (GTK_WINDOW (win)); | ||
| 493 | 581 | ||
| 494 | if (FLOATP (Vpgtk_wait_for_event_timeout)) | 582 | if (FLOATP (Vpgtk_wait_for_event_timeout)) |
| 495 | { | 583 | { |
| @@ -498,7 +586,7 @@ pgtk_make_frame_visible (struct frame *f) | |||
| 498 | int found = 0; | 586 | int found = 0; |
| 499 | int timed_out = 0; | 587 | int timed_out = 0; |
| 500 | gulong id = | 588 | gulong id = |
| 501 | g_signal_connect (win, "map-event", | 589 | g_signal_connect (FRAME_WIDGET (f), "map-event", |
| 502 | G_CALLBACK | 590 | G_CALLBACK |
| 503 | (pgtk_make_frame_visible_wait_for_map_event_cb), | 591 | (pgtk_make_frame_visible_wait_for_map_event_cb), |
| 504 | &found); | 592 | &found); |
| @@ -508,7 +596,7 @@ pgtk_make_frame_visible (struct frame *f) | |||
| 508 | &timed_out); | 596 | &timed_out); |
| 509 | while (!found && !timed_out) | 597 | while (!found && !timed_out) |
| 510 | gtk_main_iteration (); | 598 | gtk_main_iteration (); |
| 511 | g_signal_handler_disconnect (win, id); | 599 | g_signal_handler_disconnect (FRAME_WIDGET (f), id); |
| 512 | if (!timed_out) | 600 | if (!timed_out) |
| 513 | g_source_remove (src); | 601 | g_source_remove (src); |
| 514 | } | 602 | } |
| @@ -524,9 +612,7 @@ pgtk_make_frame_invisible (struct frame *f) | |||
| 524 | { | 612 | { |
| 525 | PGTK_TRACE ("pgtk_make_frame_invisible"); | 613 | PGTK_TRACE ("pgtk_make_frame_invisible"); |
| 526 | 614 | ||
| 527 | GtkWidget *win = FRAME_OUTPUT_DATA (f)->widget; | 615 | gtk_widget_hide (FRAME_WIDGET (f)); |
| 528 | |||
| 529 | gtk_widget_hide (win); | ||
| 530 | 616 | ||
| 531 | SET_FRAME_VISIBLE (f, 0); | 617 | SET_FRAME_VISIBLE (f, 0); |
| 532 | SET_FRAME_ICONIFIED (f, false); | 618 | SET_FRAME_ICONIFIED (f, false); |
| @@ -668,25 +754,89 @@ x_set_parent_frame (struct frame *f, Lisp_Object new_value, | |||
| 668 | -------------------------------------------------------------------------- */ | 754 | -------------------------------------------------------------------------- */ |
| 669 | { | 755 | { |
| 670 | struct frame *p = NULL; | 756 | struct frame *p = NULL; |
| 671 | PGTK_TRACE ("x_set_parent_frame x: %d, y: %d", f->left_pos, f->top_pos); | ||
| 672 | 757 | ||
| 673 | if (!NILP (new_value) | 758 | if (!NILP (new_value) |
| 674 | && (!FRAMEP (new_value) | 759 | && (!FRAMEP (new_value) |
| 675 | || !FRAME_LIVE_P (p = XFRAME (new_value)) || !FRAME_PGTK_P (p))) | 760 | || !FRAME_LIVE_P (p = XFRAME (new_value)) |
| 761 | || !FRAME_PGTK_P (p))) | ||
| 676 | { | 762 | { |
| 677 | store_frame_param (f, Qparent_frame, old_value); | 763 | store_frame_param (f, Qparent_frame, old_value); |
| 678 | error ("Invalid specification of `parent-frame'"); | 764 | error ("Invalid specification of `parent-frame'"); |
| 679 | } | 765 | } |
| 680 | 766 | ||
| 681 | if (p != FRAME_PARENT_FRAME (f) && (p != NULL)) | 767 | if (p != FRAME_PARENT_FRAME (f)) |
| 682 | { | 768 | { |
| 683 | block_input (); | 769 | block_input (); |
| 684 | gtk_window_set_transient_for (FRAME_NATIVE_WINDOW (f), | 770 | |
| 685 | FRAME_NATIVE_WINDOW (p)); | 771 | if (p != NULL) |
| 686 | gtk_window_set_attached_to (FRAME_NATIVE_WINDOW (f), | 772 | { |
| 687 | FRAME_GTK_WIDGET (p)); | 773 | if (FRAME_DISPLAY_INFO (f) != FRAME_DISPLAY_INFO (p)) |
| 688 | gtk_window_move (FRAME_NATIVE_WINDOW (f), f->left_pos, f->top_pos); | 774 | error ("Cross display reparent."); |
| 689 | gtk_window_set_keep_above (FRAME_NATIVE_WINDOW (f), true); | 775 | } |
| 776 | |||
| 777 | GtkWidget *fixed = FRAME_GTK_WIDGET (f); | ||
| 778 | |||
| 779 | GtkAllocation alloc; | ||
| 780 | gtk_widget_get_allocation(fixed, &alloc); | ||
| 781 | g_object_ref (fixed); | ||
| 782 | |||
| 783 | GtkCssProvider *provider = FRAME_X_OUTPUT (f)->border_color_css_provider; | ||
| 784 | |||
| 785 | { | ||
| 786 | GtkWidget *whbox_of_f = gtk_widget_get_parent (fixed); | ||
| 787 | gtk_container_remove (GTK_CONTAINER (whbox_of_f), fixed); | ||
| 788 | |||
| 789 | GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f)); | ||
| 790 | gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (provider)); | ||
| 791 | |||
| 792 | if (FRAME_GTK_OUTER_WIDGET (f)) | ||
| 793 | { | ||
| 794 | gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f)); | ||
| 795 | FRAME_GTK_OUTER_WIDGET (f) = NULL; | ||
| 796 | FRAME_OUTPUT_DATA (f)->vbox_widget = NULL; | ||
| 797 | FRAME_OUTPUT_DATA (f)->hbox_widget = NULL; | ||
| 798 | FRAME_OUTPUT_DATA (f)->menubar_widget = NULL; | ||
| 799 | FRAME_OUTPUT_DATA (f)->toolbar_widget = NULL; | ||
| 800 | FRAME_OUTPUT_DATA (f)->ttip_widget = NULL; | ||
| 801 | FRAME_OUTPUT_DATA (f)->ttip_lbl = NULL; | ||
| 802 | FRAME_OUTPUT_DATA (f)->ttip_window = NULL; | ||
| 803 | } | ||
| 804 | } | ||
| 805 | |||
| 806 | if (p == NULL) | ||
| 807 | { | ||
| 808 | xg_create_frame_outer_widgets (f); | ||
| 809 | pgtk_set_event_handler (f); | ||
| 810 | gtk_box_pack_start (GTK_BOX (f->output_data.pgtk->hbox_widget), fixed, TRUE, TRUE, 0); | ||
| 811 | f->output_data.pgtk->preferred_width = alloc.width; | ||
| 812 | f->output_data.pgtk->preferred_height = alloc.height; | ||
| 813 | x_wm_set_size_hint (f, 0, 0); | ||
| 814 | xg_frame_set_char_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, alloc.width), | ||
| 815 | FRAME_PIXEL_TO_TEXT_HEIGHT (f, alloc.height)); | ||
| 816 | gtk_widget_queue_resize (FRAME_WIDGET (f)); | ||
| 817 | gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f)); | ||
| 818 | } | ||
| 819 | else | ||
| 820 | { | ||
| 821 | GtkWidget *fixed_of_p = FRAME_GTK_WIDGET (p); | ||
| 822 | gtk_fixed_put (GTK_FIXED (fixed_of_p), fixed, f->left_pos, f->top_pos); | ||
| 823 | gtk_widget_set_size_request (fixed, alloc.width, alloc.height); | ||
| 824 | gtk_widget_show_all (fixed); | ||
| 825 | } | ||
| 826 | |||
| 827 | GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f)); | ||
| 828 | gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (provider), | ||
| 829 | GTK_STYLE_PROVIDER_PRIORITY_USER); | ||
| 830 | |||
| 831 | g_object_unref (fixed); | ||
| 832 | |||
| 833 | if (FRAME_GTK_OUTER_WIDGET (f)) { | ||
| 834 | if (EQ (x_gtk_resize_child_frames, Qresize_mode)) | ||
| 835 | gtk_container_set_resize_mode | ||
| 836 | (GTK_CONTAINER (FRAME_GTK_OUTER_WIDGET (f)), | ||
| 837 | p ? GTK_RESIZE_IMMEDIATE : GTK_RESIZE_QUEUE); | ||
| 838 | } | ||
| 839 | |||
| 690 | unblock_input (); | 840 | unblock_input (); |
| 691 | 841 | ||
| 692 | fset_parent_frame (f, new_value); | 842 | fset_parent_frame (f, new_value); |
| @@ -748,6 +898,9 @@ x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | |||
| 748 | /* doesn't work on wayland. */ | 898 | /* doesn't work on wayland. */ |
| 749 | PGTK_TRACE ("x_set_z_group"); | 899 | PGTK_TRACE ("x_set_z_group"); |
| 750 | 900 | ||
| 901 | if (!FRAME_GTK_OUTER_WIDGET (f)) | ||
| 902 | return; | ||
| 903 | |||
| 751 | if (NILP (new_value)) | 904 | if (NILP (new_value)) |
| 752 | { | 905 | { |
| 753 | gtk_window_set_keep_above (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), | 906 | gtk_window_set_keep_above (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), |
| @@ -2900,8 +3053,10 @@ pgtk_bitmap_icon (struct frame *f, Lisp_Object file) | |||
| 2900 | bool | 3053 | bool |
| 2901 | pgtk_text_icon (struct frame *f, const char *icon_name) | 3054 | pgtk_text_icon (struct frame *f, const char *icon_name) |
| 2902 | { | 3055 | { |
| 2903 | gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), NULL); | 3056 | if (FRAME_GTK_OUTER_WIDGET (f)) { |
| 2904 | gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), icon_name); | 3057 | gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), NULL); |
| 3058 | gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), icon_name); | ||
| 3059 | } | ||
| 2905 | 3060 | ||
| 2906 | return false; | 3061 | return false; |
| 2907 | } | 3062 | } |
| @@ -4392,6 +4547,9 @@ pgtk_judge_scroll_bars (struct frame *f) | |||
| 4392 | static void | 4547 | static void |
| 4393 | set_fullscreen_state (struct frame *f) | 4548 | set_fullscreen_state (struct frame *f) |
| 4394 | { | 4549 | { |
| 4550 | if (!FRAME_GTK_OUTER_WIDGET (f)) | ||
| 4551 | return; | ||
| 4552 | |||
| 4395 | GtkWindow *widget = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)); | 4553 | GtkWindow *widget = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)); |
| 4396 | switch (f->want_fullscreen) | 4554 | switch (f->want_fullscreen) |
| 4397 | { | 4555 | { |
| @@ -4571,24 +4729,27 @@ frame_highlight (struct frame *f) | |||
| 4571 | using that same window-manager binary for ever. Let's not crash just | 4729 | using that same window-manager binary for ever. Let's not crash just |
| 4572 | because of this (bug#9310). */ | 4730 | because of this (bug#9310). */ |
| 4573 | 4731 | ||
| 4732 | GtkWidget *w = FRAME_WIDGET (f); | ||
| 4733 | |||
| 4574 | char *css = | 4734 | char *css = |
| 4575 | g_strdup_printf ("decoration { border: solid %dpx #%06x; }", | 4735 | g_strdup_printf ("decoration { border: solid %dpx #%06x; }", |
| 4576 | f->border_width, | 4736 | f->border_width, |
| 4577 | (unsigned int) FRAME_X_OUTPUT (f)-> | 4737 | (unsigned int) FRAME_X_OUTPUT (f)->border_pixel & 0x00ffffff); |
| 4578 | border_pixel & 0x00ffffff); | 4738 | |
| 4579 | GtkStyleContext *ctxt = | 4739 | GtkStyleContext *ctxt = gtk_widget_get_style_context (w); |
| 4580 | gtk_widget_get_style_context (FRAME_GTK_OUTER_WIDGET (f)); | ||
| 4581 | GtkCssProvider *css_provider = gtk_css_provider_new (); | 4740 | GtkCssProvider *css_provider = gtk_css_provider_new (); |
| 4582 | gtk_css_provider_load_from_data (css_provider, css, -1, NULL); | 4741 | gtk_css_provider_load_from_data (css_provider, css, -1, NULL); |
| 4583 | gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (css_provider), | 4742 | gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (css_provider), |
| 4584 | GTK_STYLE_PROVIDER_PRIORITY_USER); | 4743 | GTK_STYLE_PROVIDER_PRIORITY_USER); |
| 4585 | g_object_unref (css_provider); | ||
| 4586 | g_free (css); | 4744 | g_free (css); |
| 4587 | 4745 | ||
| 4588 | GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider; | 4746 | GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider; |
| 4589 | FRAME_X_OUTPUT (f)->border_color_css_provider = css_provider; | 4747 | FRAME_X_OUTPUT (f)->border_color_css_provider = css_provider; |
| 4590 | if (old != NULL) | 4748 | if (old != NULL) |
| 4591 | gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old)); | 4749 | { |
| 4750 | gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old)); | ||
| 4751 | g_object_unref (old); | ||
| 4752 | } | ||
| 4592 | 4753 | ||
| 4593 | unblock_input (); | 4754 | unblock_input (); |
| 4594 | gui_update_cursor (f, true); | 4755 | gui_update_cursor (f, true); |
| @@ -4605,22 +4766,26 @@ frame_unhighlight (struct frame *f) | |||
| 4605 | block_input (); | 4766 | block_input (); |
| 4606 | /* Same as above for XSetWindowBorder (bug#9310). */ | 4767 | /* Same as above for XSetWindowBorder (bug#9310). */ |
| 4607 | 4768 | ||
| 4769 | GtkWidget *w = FRAME_WIDGET (f); | ||
| 4770 | |||
| 4608 | char *css = | 4771 | char *css = |
| 4609 | g_strdup_printf ("decoration { border: dotted %dpx #ffffff; }", | 4772 | g_strdup_printf ("decoration { border: dotted %dpx #ffffff; }", |
| 4610 | f->border_width); | 4773 | f->border_width); |
| 4611 | GtkStyleContext *ctxt = | 4774 | |
| 4612 | gtk_widget_get_style_context (FRAME_GTK_OUTER_WIDGET (f)); | 4775 | GtkStyleContext *ctxt = gtk_widget_get_style_context (w); |
| 4613 | GtkCssProvider *css_provider = gtk_css_provider_new (); | 4776 | GtkCssProvider *css_provider = gtk_css_provider_new (); |
| 4614 | gtk_css_provider_load_from_data (css_provider, css, -1, NULL); | 4777 | gtk_css_provider_load_from_data (css_provider, css, -1, NULL); |
| 4615 | gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (css_provider), | 4778 | gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (css_provider), |
| 4616 | GTK_STYLE_PROVIDER_PRIORITY_USER); | 4779 | GTK_STYLE_PROVIDER_PRIORITY_USER); |
| 4617 | g_object_unref (css_provider); | ||
| 4618 | g_free (css); | 4780 | g_free (css); |
| 4619 | 4781 | ||
| 4620 | GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider; | 4782 | GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider; |
| 4621 | FRAME_X_OUTPUT (f)->border_color_css_provider = css_provider; | 4783 | FRAME_X_OUTPUT (f)->border_color_css_provider = css_provider; |
| 4622 | if (old != NULL) | 4784 | if (old != NULL) |
| 4623 | gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old)); | 4785 | { |
| 4786 | gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old)); | ||
| 4787 | g_object_unref (old); | ||
| 4788 | } | ||
| 4624 | 4789 | ||
| 4625 | unblock_input (); | 4790 | unblock_input (); |
| 4626 | gui_update_cursor (f, true); | 4791 | gui_update_cursor (f, true); |
| @@ -4793,6 +4958,7 @@ struct pgtk_window_is_of_frame_recursive_t | |||
| 4793 | { | 4958 | { |
| 4794 | GdkWindow *window; | 4959 | GdkWindow *window; |
| 4795 | bool result; | 4960 | bool result; |
| 4961 | GtkWidget *emacs_gtk_fixed; // stop on emacsgtkfixed other than this. | ||
| 4796 | }; | 4962 | }; |
| 4797 | 4963 | ||
| 4798 | static void | 4964 | static void |
| @@ -4803,15 +4969,19 @@ pgtk_window_is_of_frame_recursive (GtkWidget * widget, gpointer data) | |||
| 4803 | if (datap->result) | 4969 | if (datap->result) |
| 4804 | return; | 4970 | return; |
| 4805 | 4971 | ||
| 4972 | if (EMACS_IS_FIXED (widget) && widget != datap->emacs_gtk_fixed) | ||
| 4973 | return; | ||
| 4974 | |||
| 4806 | if (gtk_widget_get_window (widget) == datap->window) | 4975 | if (gtk_widget_get_window (widget) == datap->window) |
| 4807 | { | 4976 | { |
| 4808 | datap->result = true; | 4977 | datap->result = true; |
| 4809 | return; | 4978 | return; |
| 4810 | } | 4979 | } |
| 4811 | 4980 | ||
| 4812 | if (GTK_IS_CONTAINER (widget)) | 4981 | if (GTK_IS_CONTAINER (widget)) { |
| 4813 | gtk_container_foreach (GTK_CONTAINER (widget), | 4982 | gtk_container_foreach (GTK_CONTAINER (widget), |
| 4814 | pgtk_window_is_of_frame_recursive, datap); | 4983 | pgtk_window_is_of_frame_recursive, datap); |
| 4984 | } | ||
| 4815 | } | 4985 | } |
| 4816 | 4986 | ||
| 4817 | static bool | 4987 | static bool |
| @@ -4820,7 +4990,8 @@ pgtk_window_is_of_frame (struct frame *f, GdkWindow * window) | |||
| 4820 | struct pgtk_window_is_of_frame_recursive_t data; | 4990 | struct pgtk_window_is_of_frame_recursive_t data; |
| 4821 | data.window = window; | 4991 | data.window = window; |
| 4822 | data.result = false; | 4992 | data.result = false; |
| 4823 | pgtk_window_is_of_frame_recursive (FRAME_GTK_OUTER_WIDGET (f), &data); | 4993 | data.emacs_gtk_fixed = FRAME_GTK_WIDGET (f); |
| 4994 | pgtk_window_is_of_frame_recursive (FRAME_WIDGET (f), &data); | ||
| 4824 | return data.result; | 4995 | return data.result; |
| 4825 | } | 4996 | } |
| 4826 | 4997 | ||
| @@ -5068,6 +5239,8 @@ pgtk_clear_under_internal_border (struct frame *f) | |||
| 5068 | } | 5239 | } |
| 5069 | } | 5240 | } |
| 5070 | 5241 | ||
| 5242 | #ifdef HAVE_PGTK | ||
| 5243 | |||
| 5071 | static void | 5244 | static void |
| 5072 | print_widget_tree_recursive (GtkWidget * w, gpointer user_data) | 5245 | print_widget_tree_recursive (GtkWidget * w, gpointer user_data) |
| 5073 | { | 5246 | { |
| @@ -5108,6 +5281,8 @@ print_widget_tree (GtkWidget * w) | |||
| 5108 | print_widget_tree_recursive (w, indent); | 5281 | print_widget_tree_recursive (w, indent); |
| 5109 | } | 5282 | } |
| 5110 | 5283 | ||
| 5284 | #endif | ||
| 5285 | |||
| 5111 | static gboolean | 5286 | static gboolean |
| 5112 | pgtk_handle_draw (GtkWidget * widget, cairo_t * cr, gpointer * data) | 5287 | pgtk_handle_draw (GtkWidget * widget, cairo_t * cr, gpointer * data) |
| 5113 | { | 5288 | { |
| @@ -5115,7 +5290,9 @@ pgtk_handle_draw (GtkWidget * widget, cairo_t * cr, gpointer * data) | |||
| 5115 | 5290 | ||
| 5116 | PGTK_TRACE ("pgtk_handle_draw"); | 5291 | PGTK_TRACE ("pgtk_handle_draw"); |
| 5117 | 5292 | ||
| 5293 | #ifdef HAVE_PGTK | ||
| 5118 | print_widget_tree (widget); | 5294 | print_widget_tree (widget); |
| 5295 | #endif | ||
| 5119 | 5296 | ||
| 5120 | GdkWindow *win = gtk_widget_get_window (widget); | 5297 | GdkWindow *win = gtk_widget_get_window (widget); |
| 5121 | 5298 | ||
| @@ -6385,11 +6562,11 @@ pgtk_set_event_handler (struct frame *f) | |||
| 6385 | NULL); | 6562 | NULL); |
| 6386 | g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "delete-event", | 6563 | g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "delete-event", |
| 6387 | G_CALLBACK (delete_event), NULL); | 6564 | G_CALLBACK (delete_event), NULL); |
| 6388 | g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "map-event", | ||
| 6389 | G_CALLBACK (map_event), NULL); | ||
| 6390 | g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "event", | 6565 | g_signal_connect (G_OBJECT (FRAME_GTK_OUTER_WIDGET (f)), "event", |
| 6391 | G_CALLBACK (pgtk_handle_event), NULL); | 6566 | G_CALLBACK (pgtk_handle_event), NULL); |
| 6392 | 6567 | ||
| 6568 | g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "map-event", | ||
| 6569 | G_CALLBACK (map_event), NULL); | ||
| 6393 | g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "size-allocate", | 6570 | g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "size-allocate", |
| 6394 | G_CALLBACK (size_allocate), NULL); | 6571 | G_CALLBACK (size_allocate), NULL); |
| 6395 | g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "key-press-event", | 6572 | g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "key-press-event", |