summaryrefslogtreecommitdiff
path: root/src/gtkutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkutil.c')
-rw-r--r--src/gtkutil.c147
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 */