diff options
| author | Jan D | 2015-05-14 13:24:53 +0200 |
|---|---|---|
| committer | Jan D | 2015-05-14 13:25:08 +0200 |
| commit | c0055ff5b03c9121ab5bf752496b09416f0f0a7d (patch) | |
| tree | afdb1d636bcf0db9c2d32f0a7e217199ae57da75 /src | |
| parent | fbda511ab8069d0115eafca411a43353b85431b1 (diff) | |
| download | emacs-c0055ff5b03c9121ab5bf752496b09416f0f0a7d.tar.gz emacs-c0055ff5b03c9121ab5bf752496b09416f0f0a7d.zip | |
Handle GTK_SCALE, fixes Bug#20432.
* gtkutil.c (xg_get_gdk_scale): New function.
(xg_frame_set_char_size)
(x_wm_set_size_hint, xg_get_default_scrollbar_width)
(xg_get_default_scrollbar_height)
(xg_update_horizontal_scrollbar_pos): Take GTK_SCALE in to account
when setting sizes (Bug#20432).
Diffstat (limited to 'src')
| -rw-r--r-- | src/gtkutil.c | 85 |
1 files changed, 65 insertions, 20 deletions
diff --git a/src/gtkutil.c b/src/gtkutil.c index b51d3388aca..c1002a5cf61 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -868,6 +868,16 @@ xg_clear_under_internal_border (struct frame *f) | |||
| 868 | } | 868 | } |
| 869 | } | 869 | } |
| 870 | 870 | ||
| 871 | static int | ||
| 872 | xg_get_gdk_scale() | ||
| 873 | { | ||
| 874 | const char *sscale = getenv("GDK_SCALE"); | ||
| 875 | int scale = 1; | ||
| 876 | |||
| 877 | if (sscale) sscanf(sscale, "%d", &scale); | ||
| 878 | return scale; | ||
| 879 | } | ||
| 880 | |||
| 871 | /* Function to handle resize of our frame. As we have a Gtk+ tool bar | 881 | /* Function to handle resize of our frame. As we have a Gtk+ tool bar |
| 872 | and a Gtk+ menu bar, we get resize events for the edit part of the | 882 | and a Gtk+ menu bar, we get resize events for the edit part of the |
| 873 | frame only. We let Gtk+ deal with the Gtk+ parts. | 883 | frame only. We let Gtk+ deal with the Gtk+ parts. |
| @@ -918,6 +928,10 @@ xg_frame_set_char_size (struct frame *f, int width, int height) | |||
| 918 | int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); | 928 | int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); |
| 919 | Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); | 929 | Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); |
| 920 | gint gwidth, gheight; | 930 | gint gwidth, gheight; |
| 931 | int totalheight = pixelheight + FRAME_TOOLBAR_HEIGHT (f) | ||
| 932 | + FRAME_MENUBAR_HEIGHT (f); | ||
| 933 | int totalwidth = pixelwidth + FRAME_TOOLBAR_WIDTH (f); | ||
| 934 | int scale = xg_get_gdk_scale (); | ||
| 921 | 935 | ||
| 922 | if (FRAME_PIXEL_HEIGHT (f) == 0) | 936 | if (FRAME_PIXEL_HEIGHT (f) == 0) |
| 923 | return; | 937 | return; |
| @@ -928,6 +942,12 @@ xg_frame_set_char_size (struct frame *f, int width, int height) | |||
| 928 | /* Do this before resize, as we don't know yet if we will be resized. */ | 942 | /* Do this before resize, as we don't know yet if we will be resized. */ |
| 929 | xg_clear_under_internal_border (f); | 943 | xg_clear_under_internal_border (f); |
| 930 | 944 | ||
| 945 | if (FRAME_VISIBLE_P (f) && scale > 1) | ||
| 946 | { | ||
| 947 | totalheight /= scale; | ||
| 948 | totalwidth /= scale; | ||
| 949 | } | ||
| 950 | |||
| 931 | /* Resize the top level widget so rows and columns remain constant. | 951 | /* Resize the top level widget so rows and columns remain constant. |
| 932 | 952 | ||
| 933 | When the frame is fullheight and we only want to change the width | 953 | When the frame is fullheight and we only want to change the width |
| @@ -942,38 +962,33 @@ xg_frame_set_char_size (struct frame *f, int width, int height) | |||
| 942 | frame_size_history_add | 962 | frame_size_history_add |
| 943 | (f, Qxg_frame_set_char_size_1, width, height, | 963 | (f, Qxg_frame_set_char_size_1, width, height, |
| 944 | list2 (make_number (gheight), | 964 | list2 (make_number (gheight), |
| 945 | make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f) | 965 | make_number (totalheight))); |
| 946 | + FRAME_MENUBAR_HEIGHT (f)))); | ||
| 947 | 966 | ||
| 948 | gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), | 967 | gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), |
| 949 | gwidth, | 968 | gwidth, |
| 950 | pixelheight + FRAME_TOOLBAR_HEIGHT (f) | 969 | totalheight); |
| 951 | + FRAME_MENUBAR_HEIGHT (f)); | ||
| 952 | } | 970 | } |
| 953 | else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f)) | 971 | else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f)) |
| 954 | { | 972 | { |
| 955 | frame_size_history_add | 973 | frame_size_history_add |
| 956 | (f, Qxg_frame_set_char_size_2, width, height, | 974 | (f, Qxg_frame_set_char_size_2, width, height, |
| 957 | list2 (make_number (gwidth), | 975 | list2 (make_number (gwidth), |
| 958 | make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f)))); | 976 | make_number (totalwidth))); |
| 959 | 977 | ||
| 960 | gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), | 978 | gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), |
| 961 | pixelwidth + FRAME_TOOLBAR_WIDTH (f), | 979 | totalwidth, |
| 962 | gheight); | 980 | gheight); |
| 963 | } | 981 | } |
| 964 | |||
| 965 | else | 982 | else |
| 966 | { | 983 | { |
| 967 | frame_size_history_add | 984 | frame_size_history_add |
| 968 | (f, Qxg_frame_set_char_size_3, width, height, | 985 | (f, Qxg_frame_set_char_size_3, width, height, |
| 969 | list2 (make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f)), | 986 | list2 (make_number (totalwidth), |
| 970 | make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f) | 987 | make_number (totalheight))); |
| 971 | + FRAME_MENUBAR_HEIGHT (f)))); | ||
| 972 | 988 | ||
| 973 | gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), | 989 | gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), |
| 974 | pixelwidth + FRAME_TOOLBAR_WIDTH (f), | 990 | totalwidth, |
| 975 | pixelheight + FRAME_TOOLBAR_HEIGHT (f) | 991 | totalheight); |
| 976 | + FRAME_MENUBAR_HEIGHT (f)); | ||
| 977 | fullscreen = Qnil; | 992 | fullscreen = Qnil; |
| 978 | } | 993 | } |
| 979 | 994 | ||
| @@ -1355,6 +1370,7 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position) | |||
| 1355 | int min_rows = 0, min_cols = 0; | 1370 | int min_rows = 0, min_cols = 0; |
| 1356 | int win_gravity = f->win_gravity; | 1371 | int win_gravity = f->win_gravity; |
| 1357 | Lisp_Object fs_state, frame; | 1372 | Lisp_Object fs_state, frame; |
| 1373 | int scale = xg_get_gdk_scale (); | ||
| 1358 | 1374 | ||
| 1359 | /* Don't set size hints during initialization; that apparently leads | 1375 | /* Don't set size hints during initialization; that apparently leads |
| 1360 | to a race condition. See the thread at | 1376 | to a race condition. See the thread at |
| @@ -1434,6 +1450,14 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position) | |||
| 1434 | hint_flags |= GDK_HINT_USER_POS; | 1450 | hint_flags |= GDK_HINT_USER_POS; |
| 1435 | } | 1451 | } |
| 1436 | 1452 | ||
| 1453 | if (scale > 1) | ||
| 1454 | { | ||
| 1455 | size_hints.base_width /= scale; | ||
| 1456 | size_hints.base_height /= scale; | ||
| 1457 | size_hints.width_inc /= scale; | ||
| 1458 | size_hints.height_inc /= scale; | ||
| 1459 | } | ||
| 1460 | |||
| 1437 | if (hint_flags != f->output_data.x->hint_flags | 1461 | if (hint_flags != f->output_data.x->hint_flags |
| 1438 | || memcmp (&size_hints, | 1462 | || memcmp (&size_hints, |
| 1439 | &f->output_data.x->size_hints, | 1463 | &f->output_data.x->size_hints, |
| @@ -3549,14 +3573,14 @@ update_theme_scrollbar_height (void) | |||
| 3549 | int | 3573 | int |
| 3550 | xg_get_default_scrollbar_width (void) | 3574 | xg_get_default_scrollbar_width (void) |
| 3551 | { | 3575 | { |
| 3552 | return scroll_bar_width_for_theme; | 3576 | return scroll_bar_width_for_theme * xg_get_gdk_scale (); |
| 3553 | } | 3577 | } |
| 3554 | 3578 | ||
| 3555 | int | 3579 | int |
| 3556 | xg_get_default_scrollbar_height (void) | 3580 | xg_get_default_scrollbar_height (void) |
| 3557 | { | 3581 | { |
| 3558 | /* Apparently there's no default height for themes. */ | 3582 | /* Apparently there's no default height for themes. */ |
| 3559 | return scroll_bar_width_for_theme; | 3583 | return scroll_bar_width_for_theme * xg_get_gdk_scale (); |
| 3560 | } | 3584 | } |
| 3561 | 3585 | ||
| 3562 | /* Return the scrollbar id for X Window WID on display DPY. | 3586 | /* Return the scrollbar id for X Window WID on display DPY. |
| @@ -3757,6 +3781,14 @@ xg_update_scrollbar_pos (struct frame *f, | |||
| 3757 | { | 3781 | { |
| 3758 | 3782 | ||
| 3759 | GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id); | 3783 | GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id); |
| 3784 | int scale = xg_get_gdk_scale (); | ||
| 3785 | |||
| 3786 | if (scale > 1) | ||
| 3787 | { | ||
| 3788 | top /= scale; | ||
| 3789 | left /= scale; | ||
| 3790 | height /= scale; | ||
| 3791 | } | ||
| 3760 | 3792 | ||
| 3761 | if (wscroll) | 3793 | if (wscroll) |
| 3762 | { | 3794 | { |
| @@ -3774,6 +3806,12 @@ xg_update_scrollbar_pos (struct frame *f, | |||
| 3774 | } | 3806 | } |
| 3775 | 3807 | ||
| 3776 | /* Move and resize to new values. */ | 3808 | /* Move and resize to new values. */ |
| 3809 | if (scale > 1) | ||
| 3810 | { | ||
| 3811 | int adj = (scale-1)*(width/scale/2); | ||
| 3812 | left -= adj; | ||
| 3813 | } | ||
| 3814 | |||
| 3777 | gtk_fixed_move (GTK_FIXED (wfixed), wparent, left, top); | 3815 | gtk_fixed_move (GTK_FIXED (wfixed), wparent, left, top); |
| 3778 | gtk_widget_style_get (wscroll, "min-slider-length", &msl, NULL); | 3816 | gtk_widget_style_get (wscroll, "min-slider-length", &msl, NULL); |
| 3779 | if (msl > height) | 3817 | if (msl > height) |
| @@ -3791,11 +3829,18 @@ xg_update_scrollbar_pos (struct frame *f, | |||
| 3791 | gtk_widget_queue_draw (wfixed); | 3829 | gtk_widget_queue_draw (wfixed); |
| 3792 | gdk_window_process_all_updates (); | 3830 | gdk_window_process_all_updates (); |
| 3793 | if (oldx != -1 && oldw > 0 && oldh > 0) | 3831 | if (oldx != -1 && oldw > 0 && oldh > 0) |
| 3794 | /* Clear under old scroll bar position. This must be done after | 3832 | { |
| 3795 | the gtk_widget_queue_draw and gdk_window_process_all_updates | 3833 | /* Clear under old scroll bar position. This must be done after |
| 3796 | above. */ | 3834 | the gtk_widget_queue_draw and gdk_window_process_all_updates |
| 3797 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 3835 | above. */ |
| 3798 | oldx, oldy, oldw, oldh); | 3836 | if (scale > 1) |
| 3837 | { | ||
| 3838 | oldw += (scale-1)*oldw; | ||
| 3839 | oldx -= (scale-1)*oldw; | ||
| 3840 | } | ||
| 3841 | x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | ||
| 3842 | oldx, oldy, oldw, oldh); | ||
| 3843 | } | ||
| 3799 | 3844 | ||
| 3800 | /* GTK does not redraw until the main loop is entered again, but | 3845 | /* GTK does not redraw until the main loop is entered again, but |
| 3801 | if there are no X events pending we will not enter it. So we sync | 3846 | if there are no X events pending we will not enter it. So we sync |