#ifdef HAVE_GTK3
#include <gtk/gtkx.h>
+#include "emacsgtkfixed.h"
#endif
#define FRAME_TOTAL_PIXEL_HEIGHT(f) \
#define XG_BIN_CHILD(x) gtk_bin_get_child (GTK_BIN (x))
-/* Get the current value of the range, truncated to an integer. */
-static int
-int_gtk_range_get_value (GtkRange *range)
-{
- return gtk_range_get_value (range);
-}
+static void update_theme_scrollbar_width (void);
\f
/***********************************************************************
struct input_event event;
GdkDisplay *gdpy = (GdkDisplay *) user_data;
const char *display_name = gdk_display_get_name (gdpy);
+ Display *dpy = GDK_DISPLAY_XDISPLAY (gdpy);
EVENT_INIT (event);
event.kind = CONFIG_CHANGED_EVENT;
- event.frame_or_window = make_string (display_name, strlen (display_name));
+ event.frame_or_window = build_string (display_name);
/* Theme doesn't change often, so intern is called seldom. */
event.arg = intern ("theme-name");
kbd_buffer_store_event (&event);
+
+ update_theme_scrollbar_width ();
+
+ /* If scroll bar width changed, we need set the new size on all frames
+ on this display. */
+ if (dpy)
+ {
+ Lisp_Object rest, frame;
+ FOR_EACH_FRAME (rest, frame)
+ {
+ FRAME_PTR f = XFRAME (frame);
+ if (FRAME_X_DISPLAY (f) == dpy)
+ {
+ x_set_scroll_bar_default_width (f);
+ xg_frame_set_char_size (f, FRAME_COLS (f), FRAME_LINES (f));
+ }
+ }
+ }
}
/* Called when a delete-event occurs on WIDGET. */
wvbox = gtk_vbox_new (FALSE, 0);
whbox = gtk_hbox_new (FALSE, 0);
- wfixed = gtk_fixed_new (); /* Must have this to place scroll bars */
+
+#ifdef HAVE_GTK3
+ wfixed = emacs_fixed_new ();
+#else
+ wfixed = gtk_fixed_new ();
+#endif
if (! wtop || ! wvbox || ! whbox || ! wfixed)
{
gtk_widget_modify_style (wfixed, style);
#else
gtk_widget_set_can_focus (wfixed, TRUE);
+ gtk_window_set_resizable (GTK_WINDOW (wtop), TRUE);
#endif
#ifdef USE_GTK_TOOLTIP
size_hints.min_width = base_width + min_cols * size_hints.width_inc;
size_hints.min_height = base_height + min_rows * size_hints.height_inc;
+#ifdef HAVE_GTK3
+ /* Gtk3 ignores min width/height and overwrites them with its own idea
+ of min width/height. Put out min values to the widget so Gtk
+ gets the same value we want it to be. Without this, a user can't
+ shrink an Emacs frame.
+ */
+ if (FRAME_GTK_WIDGET (f))
+ emacs_fixed_set_min_size (EMACS_FIXED (FRAME_GTK_WIDGET (f)),
+ size_hints.min_width,
+ size_hints.min_height);
+#endif
+
/* These currently have a one to one mapping with the X values, but I
don't think we should rely on that. */
hint_flags |= GDK_HINT_WIN_GRAVITY;
int xg_ignore_gtk_scrollbar;
+/* The width of the scroll bar for the current theme. */
+
+static int scroll_bar_width_for_theme;
+
/* Xlib's `Window' fits in 32 bits. But we want to store pointers, and they
may be larger than 32 bits. Keep a mapping from integer index to widget
pointers to get around the 32 bit limitation. */
return 0;
}
+static void
+update_theme_scrollbar_width (void)
+{
+#ifdef HAVE_GTK3
+ GtkAdjustment *vadj;
+#else
+ GtkObject *vadj;
+#endif
+ GtkWidget *wscroll;
+ int w = 0, b = 0;
+
+ vadj = gtk_adjustment_new (XG_SB_MIN, XG_SB_MIN, XG_SB_MAX, 0.1, 0.1, 0.1);
+ wscroll = gtk_vscrollbar_new (GTK_ADJUSTMENT (vadj));
+ g_object_ref_sink (G_OBJECT (wscroll));
+ gtk_widget_style_get (wscroll, "slider-width", &w, "trough-border", &b, NULL);
+ gtk_widget_destroy (wscroll);
+ g_object_unref (G_OBJECT (wscroll));
+ w += 2*b;
+ if (w < 16) w = 16;
+ scroll_bar_width_for_theme = w;
+}
+
+int
+xg_get_default_scrollbar_width (void)
+{
+ return scroll_bar_width_for_theme;
+}
+
/* Return the scrollbar id for X Window WID on display DPY.
Return -1 if WID not in id_to_widget. */
static void
xg_gtk_scroll_destroy (GtkWidget *widget, gpointer data)
{
- int id = (int) (EMACS_INT) data; /* The EMACS_INT cast avoids a warning. */
+ int id = (intptr_t) data;
xg_remove_widget_from_map (id);
}
{
GtkWidget *wscroll;
GtkWidget *webox;
- int scroll_id;
+ intptr_t scroll_id;
#ifdef HAVE_GTK3
GtkAdjustment *vadj;
#else
scroll_id = xg_store_widget_in_map (wscroll);
- /* The EMACS_INT cast avoids a warning. */
g_signal_connect (G_OBJECT (wscroll),
"destroy",
G_CALLBACK (xg_gtk_scroll_destroy),
- (gpointer) (EMACS_INT) scroll_id);
+ (gpointer) scroll_id);
g_signal_connect (G_OBJECT (wscroll),
"change-value",
scroll_callback,
}
}
+/* Get the current value of the range, truncated to an integer. */
+
+static int
+int_gtk_range_get_value (GtkRange *range)
+{
+ return gtk_range_get_value (range);
+}
+
+
/* Set the thumb size and position of scroll bar BAR. We are currently
displaying PORTION out of a whole WHOLE, and our position POSITION. */
GdkEventButton *event,
gpointer user_data)
{
- /* Casts to avoid warnings when gpointer is 64 bits and int is 32 bits */
- gpointer ptr = (gpointer) (EMACS_INT) event->state;
+ intptr_t state = event->state;
+ gpointer ptr = (gpointer) state;
g_object_set_data (G_OBJECT (widget), XG_TOOL_BAR_LAST_MODIFIER, ptr);
return FALSE;
}
static void
xg_tool_bar_callback (GtkWidget *w, gpointer client_data)
{
- /* The EMACS_INT cast avoids a warning. */
- int idx = (int) (EMACS_INT) client_data;
+ intptr_t idx = (intptr_t) client_data;
gpointer gmod = g_object_get_data (G_OBJECT (w), XG_TOOL_BAR_LAST_MODIFIER);
- int mod = (int) (EMACS_INT) gmod;
+ intptr_t mod = (intptr_t) gmod;
FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA);
Lisp_Object key, frame;
GdkEventCrossing *event,
gpointer client_data)
{
- /* The EMACS_INT cast avoids a warning. */
- int idx = (int) (EMACS_INT) client_data;
+ intptr_t idx = (intptr_t) client_data;
FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA);
Lisp_Object help, frame;
if (wimage)
{
- /* The EMACS_INT cast avoids a warning. */
+ intptr_t ii = i;
+ gpointer gi = (gpointer) ii;
+
g_signal_connect (G_OBJECT (ti), "create-menu-proxy",
G_CALLBACK (xg_tool_bar_menu_proxy),
- (gpointer) (EMACS_INT) i);
+ gi);
g_signal_connect (G_OBJECT (wb), "clicked",
G_CALLBACK (xg_tool_bar_callback),
- (gpointer) (EMACS_INT) i);
+ gi);
g_object_set_data (G_OBJECT (weventbox), XG_FRAME_DATA, (gpointer)f);
g_signal_connect (G_OBJECT (weventbox),
"enter-notify-event",
G_CALLBACK (xg_tool_bar_help_callback),
- (gpointer) (EMACS_INT) i);
+ gi);
g_signal_connect (G_OBJECT (weventbox),
"leave-notify-event",
G_CALLBACK (xg_tool_bar_help_callback),
- (gpointer) (EMACS_INT) i);
+ gi);
}
if (wbutton) *wbutton = wb;
(GTK_TYPE_MENU_SHELL));
gtk_binding_entry_add_signal (binding_set, GDK_KEY_g, GDK_CONTROL_MASK,
"cancel", 0);
+ update_theme_scrollbar_width ();
}
#endif /* USE_GTK */