diff options
Diffstat (limited to 'src/gtkutil.c')
-rw-r--r-- | src/gtkutil.c | 147 |
1 files changed, 94 insertions, 53 deletions
diff --git a/src/gtkutil.c b/src/gtkutil.c index fe1680b21b5..b130692c87a 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -147,7 +147,9 @@ struct xg_frame_tb_info GtkTextDirection dir; }; +#ifdef HAVE_XWIDGETS bool xg_gtk_initialized; /* Used to make sure xwidget calls are possible */ +#endif static GtkWidget * xg_get_widget_from_map (ptrdiff_t idx); @@ -260,8 +262,8 @@ xg_display_close (Display *dpy) } #if GTK_CHECK_VERSION (2, 0, 0) && ! GTK_CHECK_VERSION (2, 10, 0) - /* GTK 2.2-2.8 has a bug that makes gdk_display_close crash (bug - https://gitlab.gnome.org/GNOME/gtk/issues/221). This way we + /* GTK 2.2-2.8 has a bug that makes gdk_display_close crash + <https://gitlab.gnome.org/GNOME/gtk/issues/221>. This way we can continue running, but there will be memory leaks. */ g_object_run_dispose (G_OBJECT (gdpy)); #else @@ -366,7 +368,11 @@ xg_get_image_for_pixmap (struct frame *f, GtkWidget *widget, GtkImage *old_widget) { +#if defined USE_CAIRO && GTK_CHECK_VERSION (3, 10, 0) + cairo_surface_t *surface; +#else GdkPixbuf *icon_buf; +#endif /* If we have a file, let GTK do all the image handling. This seems to be the only way to make insensitive and activated icons @@ -394,6 +400,17 @@ xg_get_image_for_pixmap (struct frame *f, on a monochrome display, and sometimes bad on all displays with certain themes. */ +#if defined USE_CAIRO && GTK_CHECK_VERSION (3, 10, 0) + surface = img->cr_data; + + if (surface) + { + if (! old_widget) + old_widget = GTK_IMAGE (gtk_image_new_from_surface (surface)); + else + gtk_image_set_from_surface (old_widget, surface); + } +#else /* This is a workaround to make icons look good on pseudo color displays. Apparently GTK expects the images to have an alpha channel. If they don't, insensitive and activated icons will @@ -414,6 +431,7 @@ xg_get_image_for_pixmap (struct frame *f, g_object_unref (G_OBJECT (icon_buf)); } +#endif return GTK_WIDGET (old_widget); } @@ -689,6 +707,7 @@ qttip_cb (GtkWidget *widget, g_signal_connect (x->ttip_lbl, "hierarchy-changed", G_CALLBACK (hierarchy_ch_cb), f); } + return FALSE; } @@ -715,7 +734,8 @@ xg_prepare_tooltip (struct frame *f, GtkRequisition req; Lisp_Object encoded_string; - if (!x->ttip_lbl) return 0; + if (!x->ttip_lbl) + return FALSE; block_input (); encoded_string = ENCODE_UTF_8 (string); @@ -747,7 +767,7 @@ xg_prepare_tooltip (struct frame *f, unblock_input (); - return 1; + return TRUE; #endif /* USE_GTK_TOOLTIP */ } @@ -764,24 +784,24 @@ xg_show_tooltip (struct frame *f, int root_x, int root_y) block_input (); gtk_window_move (x->ttip_window, root_x / xg_get_scale (f), root_y / xg_get_scale (f)); - gtk_widget_show_all (GTK_WIDGET (x->ttip_window)); + gtk_widget_show (GTK_WIDGET (x->ttip_window)); unblock_input (); } #endif } + /* Hide tooltip if shown. Do nothing if not shown. Return true if tip was hidden, false if not (i.e. not using system tooltips). */ - bool xg_hide_tooltip (struct frame *f) { - bool ret = 0; #ifdef USE_GTK_TOOLTIP if (f->output_data.x->ttip_window) { GtkWindow *win = f->output_data.x->ttip_window; + block_input (); gtk_widget_hide (GTK_WIDGET (win)); @@ -794,10 +814,10 @@ xg_hide_tooltip (struct frame *f) } unblock_input (); - ret = 1; + return TRUE; } #endif - return ret; + return FALSE; } @@ -963,7 +983,7 @@ xg_frame_set_char_size (struct frame *f, int width, int height) { frame_size_history_add (f, Qxg_frame_set_char_size_1, width, height, - list2 (make_number (gheight), make_number (totalheight))); + list2i (gheight, totalheight)); gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), gwidth, totalheight); @@ -972,7 +992,7 @@ xg_frame_set_char_size (struct frame *f, int width, int height) { frame_size_history_add (f, Qxg_frame_set_char_size_2, width, height, - list2 (make_number (gwidth), make_number (totalwidth))); + list2i (gwidth, totalwidth)); gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), totalwidth, gheight); @@ -981,7 +1001,7 @@ xg_frame_set_char_size (struct frame *f, int width, int height) { frame_size_history_add (f, Qxg_frame_set_char_size_3, width, height, - list2 (make_number (totalwidth), make_number (totalheight))); + list2i (totalwidth, totalheight)); gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), totalwidth, totalheight); @@ -1066,16 +1086,23 @@ static void xg_set_widget_bg (struct frame *f, GtkWidget *w, unsigned long pixel) { #ifdef HAVE_GTK3 - GdkRGBA bg; XColor xbg; xbg.pixel = pixel; if (XQueryColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &xbg)) { - bg.red = (double)xbg.red/65535.0; - bg.green = (double)xbg.green/65535.0; - bg.blue = (double)xbg.blue/65535.0; - bg.alpha = 1.0; - gtk_widget_override_background_color (w, GTK_STATE_FLAG_NORMAL, &bg); + const char format[] = "* { background-color: #%02x%02x%02x; }"; + /* The format is always longer than the resulting string. */ + char buffer[sizeof format]; + int n = snprintf(buffer, sizeof buffer, format, + xbg.red >> 8, xbg.green >> 8, xbg.blue >> 8); + eassert (n > 0); + eassert (n < sizeof buffer); + GtkCssProvider *provider = gtk_css_provider_new (); + gtk_css_provider_load_from_data (provider, buffer, -1, NULL); + gtk_style_context_add_provider (gtk_widget_get_style_context(w), + GTK_STYLE_PROVIDER (provider), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + g_clear_object (&provider); } #else GdkColor bg; @@ -1239,9 +1266,11 @@ xg_create_frame_widgets (struct frame *f) X and GTK+ drawing to a pure GTK+ build. */ gtk_widget_set_double_buffered (wfixed, FALSE); +#if ! GTK_CHECK_VERSION (3, 22, 0) gtk_window_set_wmclass (GTK_WINDOW (wtop), SSDATA (Vx_resource_name), SSDATA (Vx_resource_class)); +#endif /* Add callback to do nothing on WM_DELETE_WINDOW. The default in GTK is to destroy the widget. We want Emacs to do that instead. */ @@ -1372,7 +1401,6 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position) GdkGeometry size_hints; gint hint_flags = 0; int base_width, base_height; - int min_rows = 0, min_cols = 0; int win_gravity = f->win_gravity; Lisp_Object fs_state, frame; int scale = xg_get_scale (f); @@ -1421,13 +1449,10 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position) base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 1) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f); - if (min_cols > 0) --min_cols; /* We used one col in base_width = ... 1); */ - if (min_rows > 0) --min_rows; /* We used one row in base_height = ... 1); */ - size_hints.base_width = base_width; size_hints.base_height = base_height; - size_hints.min_width = base_width + min_cols * FRAME_COLUMN_WIDTH (f); - size_hints.min_height = base_height + min_rows * FRAME_LINE_HEIGHT (f); + size_hints.min_width = base_width; + size_hints.min_height = base_height; /* These currently have a one to one mapping with the X values, but I don't think we should rely on that. */ @@ -1859,7 +1884,7 @@ xg_maybe_add_timer (gpointer data) if (timespec_valid_p (next_time)) { time_t s = next_time.tv_sec; - int per_ms = TIMESPEC_RESOLUTION / 1000; + int per_ms = TIMESPEC_HZ / 1000; int ms = (next_time.tv_nsec + per_ms - 1) / per_ms; if (s <= ((guint) -1 - ms) / 1000) dd->timerid = g_timeout_add (s * 1000 + ms, xg_maybe_add_timer, dd); @@ -4111,8 +4136,10 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, if (int_gtk_range_get_value (GTK_RANGE (wscroll)) != value) gtk_range_set_value (GTK_RANGE (wscroll), (gdouble)value); +#if ! GTK_CHECK_VERSION (3, 18, 0) else if (changed) gtk_adjustment_changed (adj); +#endif xg_ignore_gtk_scrollbar = 0; @@ -4149,7 +4176,9 @@ xg_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar, gtk_adjustment_configure (adj, (gdouble) value, (gdouble) lower, (gdouble) upper, (gdouble) step_increment, (gdouble) page_increment, (gdouble) pagesize); +#if ! GTK_CHECK_VERSION (3, 18, 0) gtk_adjustment_changed (adj); +#endif unblock_input (); } } @@ -4243,23 +4272,16 @@ xg_get_page_setup (void) eassume (false); } - return listn (CONSTYPE_HEAP, 7, - Fcons (Qorientation, orientation_symbol), -#define MAKE_FLOAT_PAGE_SETUP(f) make_float (f (page_setup, GTK_UNIT_POINTS)) - Fcons (Qwidth, - MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_page_width)), - Fcons (Qheight, - MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_page_height)), - Fcons (Qleft_margin, - MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_left_margin)), - Fcons (Qright_margin, - MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_right_margin)), - Fcons (Qtop_margin, - MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_top_margin)), - Fcons (Qbottom_margin, - MAKE_FLOAT_PAGE_SETUP (gtk_page_setup_get_bottom_margin)) -#undef MAKE_FLOAT_PAGE_SETUP - ); +#define GETSETUP(f) make_float (f (page_setup, GTK_UNIT_POINTS)) + return + list (Fcons (Qorientation, orientation_symbol), + Fcons (Qwidth, GETSETUP (gtk_page_setup_get_page_width)), + Fcons (Qheight, GETSETUP (gtk_page_setup_get_page_height)), + Fcons (Qleft_margin, GETSETUP (gtk_page_setup_get_left_margin)), + Fcons (Qright_margin, GETSETUP (gtk_page_setup_get_right_margin)), + Fcons (Qtop_margin, GETSETUP (gtk_page_setup_get_top_margin)), + Fcons (Qbottom_margin, GETSETUP (gtk_page_setup_get_bottom_margin))); +#undef GETSETUP } static void @@ -4267,7 +4289,7 @@ draw_page (GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, gpointer user_data) { Lisp_Object frames = *((Lisp_Object *) user_data); - struct frame *f = XFRAME (Fnth (make_number (page_nr), frames)); + struct frame *f = XFRAME (Fnth (make_fixnum (page_nr), frames)); cairo_t *cr = gtk_print_context_get_cairo_context (context); x_cr_draw_frame (cr, f); @@ -4284,7 +4306,7 @@ xg_print_frames_dialog (Lisp_Object frames) gtk_print_operation_set_print_settings (print, print_settings); if (page_setup != NULL) gtk_print_operation_set_default_page_setup (print, page_setup); - gtk_print_operation_set_n_pages (print, XINT (Flength (frames))); + gtk_print_operation_set_n_pages (print, list_length (frames)); g_signal_connect (print, "draw-page", G_CALLBACK (draw_page), &frames); res = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, NULL, NULL); @@ -4755,9 +4777,15 @@ xg_tool_item_stale_p (GtkWidget *wbutton, const char *stock_name, { gpointer gold_img = g_object_get_data (G_OBJECT (wimage), XG_TOOL_BAR_IMAGE_DATA); +#if defined USE_CAIRO && GTK_CHECK_VERSION (3, 10, 0) + void *old_img = (void *) gold_img; + if (old_img != img->cr_data) + return 1; +#else Pixmap old_img = (Pixmap) gold_img; if (old_img != img->pixmap) return 1; +#endif } /* Check button configuration and label. */ @@ -4877,18 +4905,18 @@ update_frame_tool_bar (struct frame *f) block_input (); - if (RANGED_INTEGERP (1, Vtool_bar_button_margin, INT_MAX)) + if (RANGED_FIXNUMP (1, Vtool_bar_button_margin, INT_MAX)) { - hmargin = XFASTINT (Vtool_bar_button_margin); - vmargin = XFASTINT (Vtool_bar_button_margin); + hmargin = XFIXNAT (Vtool_bar_button_margin); + vmargin = XFIXNAT (Vtool_bar_button_margin); } else if (CONSP (Vtool_bar_button_margin)) { - if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin), INT_MAX)) - hmargin = XFASTINT (XCAR (Vtool_bar_button_margin)); + if (RANGED_FIXNUMP (1, XCAR (Vtool_bar_button_margin), INT_MAX)) + hmargin = XFIXNAT (XCAR (Vtool_bar_button_margin)); - if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin), INT_MAX)) - vmargin = XFASTINT (XCDR (Vtool_bar_button_margin)); + if (RANGED_FIXNUMP (1, XCDR (Vtool_bar_button_margin), INT_MAX)) + vmargin = XFIXNAT (XCDR (Vtool_bar_button_margin)); } /* The natural size (i.e. when GTK uses 0 as margin) looks best, @@ -5049,7 +5077,13 @@ update_frame_tool_bar (struct frame *f) img = IMAGE_FROM_ID (f, img_id); prepare_image_for_display (f, img); - if (img->load_failed_p || img->pixmap == None) + if (img->load_failed_p +#if defined USE_CAIRO && GTK_CHECK_VERSION (3, 10, 0) + || img->cr_data == NULL +#else + || img->pixmap == None +#endif + ) { if (ti) gtk_container_remove (GTK_CONTAINER (wtoolbar), @@ -5099,7 +5133,12 @@ update_frame_tool_bar (struct frame *f) { w = xg_get_image_for_pixmap (f, img, x->widget, NULL); g_object_set_data (G_OBJECT (w), XG_TOOL_BAR_IMAGE_DATA, - (gpointer)img->pixmap); +#if defined USE_CAIRO && GTK_CHECK_VERSION (3, 10, 0) + (gpointer)img->cr_data +#else + (gpointer)img->pixmap +#endif + ); } #if GTK_CHECK_VERSION (3, 14, 0) @@ -5309,7 +5348,9 @@ xg_initialize (void) x_last_font_name = NULL; #endif +#ifdef HAVE_XWIDGETS xg_gtk_initialized = true; +#endif } #endif /* USE_GTK */ |