summaryrefslogtreecommitdiff
path: root/src/gtkutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkutil.c')
-rw-r--r--src/gtkutil.c170
1 files changed, 80 insertions, 90 deletions
diff --git a/src/gtkutil.c b/src/gtkutil.c
index e323216bb79..3d35a3dee81 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -48,6 +48,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "emacsgtkfixed.h"
#endif
+#ifdef HAVE_XDBE
+#include <X11/extensions/Xdbe.h>
+#endif
+
#ifndef HAVE_GTK_WIDGET_SET_HAS_WINDOW
#define gtk_widget_set_has_window(w, b) \
(gtk_fixed_set_has_window (GTK_FIXED (w), b))
@@ -143,6 +147,8 @@ struct xg_frame_tb_info
GtkTextDirection dir;
};
+static GtkWidget * xg_get_widget_from_map (ptrdiff_t idx);
+
/***********************************************************************
Display handling functions
@@ -815,12 +821,6 @@ xg_clear_under_internal_border (struct frame *f)
{
if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
{
-#ifndef USE_CAIRO
- GtkWidget *wfixed = f->output_data.x->edit_widget;
-
- gtk_widget_queue_draw (wfixed);
- gdk_window_process_all_updates ();
-#endif
x_clear_area (f, 0, 0,
FRAME_PIXEL_WIDTH (f), FRAME_INTERNAL_BORDER_WIDTH (f));
@@ -1233,6 +1233,7 @@ xg_create_frame_widgets (struct frame *f)
by callers of this function. */
gtk_widget_realize (wfixed);
FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (wfixed);
+ initial_set_up_x_back_buffer (f);
/* Since GTK clears its window by filling with the background color,
we must keep X and GTK background in sync. */
@@ -1296,8 +1297,11 @@ xg_free_frame_widgets (struct frame *f)
if (tbinfo)
xfree (tbinfo);
+ /* x_free_frame_resources should have taken care of it */
+ eassert (!FRAME_X_DOUBLE_BUFFERED_P (f));
gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
FRAME_X_WINDOW (f) = 0; /* Set to avoid XDestroyWindow in xterm.c */
+ FRAME_X_RAW_DRAWABLE (f) = 0;
FRAME_GTK_OUTER_WIDGET (f) = 0;
#ifdef USE_GTK_TOOLTIP
if (x->ttip_lbl)
@@ -1440,6 +1444,18 @@ xg_set_background_color (struct frame *f, unsigned long bg)
{
block_input ();
xg_set_widget_bg (f, FRAME_GTK_WIDGET (f), FRAME_BACKGROUND_PIXEL (f));
+
+ Lisp_Object bar;
+ for (bar = FRAME_SCROLL_BARS (f);
+ !NILP (bar);
+ bar = XSCROLL_BAR (bar)->next)
+ {
+ GtkWidget *scrollbar =
+ xg_get_widget_from_map (XSCROLL_BAR (bar)->x_window);
+ GtkWidget *webox = gtk_widget_get_parent (scrollbar);
+ xg_set_widget_bg (f, webox, FRAME_BACKGROUND_PIXEL (f));
+ }
+
unblock_input ();
}
}
@@ -1829,7 +1845,8 @@ xg_get_file_with_chooser (struct frame *f,
{
char msgbuf[1024];
- GtkWidget *filewin, *wtoggle, *wbox, *wmessage IF_LINT (= NULL);
+ GtkWidget *filewin, *wtoggle, *wbox;
+ GtkWidget *wmessage UNINIT;
GtkWindow *gwin = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f));
GtkFileChooserAction action = (mustmatch_p ?
GTK_FILE_CHOOSER_ACTION_OPEN :
@@ -2264,7 +2281,6 @@ xg_mark_data (void)
}
}
-
/* Callback called when a menu item is destroyed. Used to free data.
W is the widget that is being destroyed (not used).
CLIENT_DATA points to the xg_menu_item_cb_data associated with the W. */
@@ -3568,44 +3584,23 @@ xg_gtk_scroll_destroy (GtkWidget *widget, gpointer data)
xg_remove_widget_from_map (id);
}
-/* Create a scroll bar widget for frame F. Store the scroll bar
- in BAR.
- SCROLL_CALLBACK is the callback to invoke when the value of the
- bar changes.
- END_CALLBACK is the callback to invoke when scrolling ends.
- SCROLL_BAR_NAME is the name we use for the scroll bar. Can be used
- to set resources for the widget. */
-
-void
-xg_create_scroll_bar (struct frame *f,
- struct scroll_bar *bar,
- GCallback scroll_callback,
- GCallback end_callback,
- const char *scroll_bar_name)
+static void
+xg_finish_scroll_bar_creation (struct frame *f,
+ GtkWidget *wscroll,
+ struct scroll_bar *bar,
+ GCallback scroll_callback,
+ GCallback end_callback,
+ const char *scroll_bar_name)
{
- GtkWidget *wscroll;
- GtkWidget *webox;
- intptr_t scroll_id;
-#ifdef HAVE_GTK3
- GtkAdjustment *vadj;
-#else
- GtkObject *vadj;
-#endif
+ GtkWidget *webox = gtk_event_box_new ();
- /* Page, step increment values are not so important here, they
- will be corrected in x_set_toolkit_scroll_bar_thumb. */
- vadj = gtk_adjustment_new (XG_SB_MIN, XG_SB_MIN, XG_SB_MAX,
- 0.1, 0.1, 0.1);
-
- wscroll = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (vadj));
- webox = gtk_event_box_new ();
gtk_widget_set_name (wscroll, scroll_bar_name);
#ifndef HAVE_GTK3
gtk_range_set_update_policy (GTK_RANGE (wscroll), GTK_UPDATE_CONTINUOUS);
#endif
g_object_set_data (G_OBJECT (wscroll), XG_FRAME_DATA, (gpointer)f);
- scroll_id = xg_store_widget_in_map (wscroll);
+ ptrdiff_t scroll_id = xg_store_widget_in_map (wscroll);
g_signal_connect (G_OBJECT (wscroll),
"destroy",
@@ -3629,11 +3624,52 @@ xg_create_scroll_bar (struct frame *f,
gtk_fixed_put (GTK_FIXED (f->output_data.x->edit_widget), webox, -1, -1);
gtk_container_add (GTK_CONTAINER (webox), wscroll);
+ xg_set_widget_bg (f, webox, FRAME_BACKGROUND_PIXEL (f));
+
+ /* N.B. The event box doesn't become a real X11 window until we ask
+ for its XID via GTK_WIDGET_TO_X_WIN. If the event box is not a
+ real X window, it and its scroll-bar child try to draw on the
+ Emacs main window, which we draw over using Xlib. */
+ gtk_widget_realize (webox);
+ GTK_WIDGET_TO_X_WIN (webox);
/* Set the cursor to an arrow. */
xg_set_cursor (webox, FRAME_DISPLAY_INFO (f)->xg_cursor);
bar->x_window = scroll_id;
+}
+
+/* Create a scroll bar widget for frame F. Store the scroll bar
+ in BAR.
+ SCROLL_CALLBACK is the callback to invoke when the value of the
+ bar changes.
+ END_CALLBACK is the callback to invoke when scrolling ends.
+ SCROLL_BAR_NAME is the name we use for the scroll bar. Can be used
+ to set resources for the widget. */
+
+void
+xg_create_scroll_bar (struct frame *f,
+ struct scroll_bar *bar,
+ GCallback scroll_callback,
+ GCallback end_callback,
+ const char *scroll_bar_name)
+{
+ GtkWidget *wscroll;
+#ifdef HAVE_GTK3
+ GtkAdjustment *vadj;
+#else
+ GtkObject *vadj;
+#endif
+
+ /* Page, step increment values are not so important here, they
+ will be corrected in x_set_toolkit_scroll_bar_thumb. */
+ vadj = gtk_adjustment_new (XG_SB_MIN, XG_SB_MIN, XG_SB_MAX,
+ 0.1, 0.1, 0.1);
+
+ wscroll = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (vadj));
+
+ xg_finish_scroll_bar_creation (f, wscroll, bar, scroll_callback,
+ end_callback, scroll_bar_name);
bar->horizontal = 0;
}
@@ -3651,8 +3687,6 @@ xg_create_horizontal_scroll_bar (struct frame *f,
const char *scroll_bar_name)
{
GtkWidget *wscroll;
- GtkWidget *webox;
- intptr_t scroll_id;
#ifdef HAVE_GTK3
GtkAdjustment *hadj;
#else
@@ -3665,42 +3699,9 @@ xg_create_horizontal_scroll_bar (struct frame *f,
0.1, 0.1, 0.1);
wscroll = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (hadj));
- webox = gtk_event_box_new ();
- gtk_widget_set_name (wscroll, scroll_bar_name);
-#ifndef HAVE_GTK3
- gtk_range_set_update_policy (GTK_RANGE (wscroll), GTK_UPDATE_CONTINUOUS);
-#endif
- g_object_set_data (G_OBJECT (wscroll), XG_FRAME_DATA, (gpointer)f);
-
- scroll_id = xg_store_widget_in_map (wscroll);
-
- g_signal_connect (G_OBJECT (wscroll),
- "destroy",
- G_CALLBACK (xg_gtk_scroll_destroy),
- (gpointer) scroll_id);
- g_signal_connect (G_OBJECT (wscroll),
- "change-value",
- scroll_callback,
- (gpointer) bar);
- g_signal_connect (G_OBJECT (wscroll),
- "button-release-event",
- end_callback,
- (gpointer) bar);
-
- /* The scroll bar widget does not draw on a window of its own. Instead
- it draws on the parent window, in this case the edit widget. So
- whenever the edit widget is cleared, the scroll bar needs to redraw
- also, which causes flicker. Put an event box between the edit widget
- and the scroll bar, so the scroll bar instead draws itself on the
- event box window. */
- gtk_fixed_put (GTK_FIXED (f->output_data.x->edit_widget), webox, -1, -1);
- gtk_container_add (GTK_CONTAINER (webox), wscroll);
-
- /* Set the cursor to an arrow. */
- xg_set_cursor (webox, FRAME_DISPLAY_INFO (f)->xg_cursor);
-
- bar->x_window = scroll_id;
+ xg_finish_scroll_bar_creation (f, wscroll, bar, scroll_callback,
+ end_callback, scroll_bar_name);
bar->horizontal = 1;
}
@@ -3769,16 +3770,10 @@ xg_update_scrollbar_pos (struct frame *f,
gtk_widget_show_all (wparent);
gtk_widget_set_size_request (wscroll, width, height);
}
-#ifndef USE_CAIRO
- gtk_widget_queue_draw (wfixed);
- gdk_window_process_all_updates ();
-#endif
if (oldx != -1 && oldw > 0 && oldh > 0)
{
- /* Clear under old scroll bar position. This must be done after
- the gtk_widget_queue_draw and gdk_window_process_all_updates
- above. */
- oldw += (scale - 1) * oldw;
+ /* Clear under old scroll bar position. */
+ oldw += (scale - 1) * oldw;
oldx -= (scale - 1) * oldw;
x_clear_area (f, oldx, oldy, oldw, oldh);
}
@@ -3840,14 +3835,9 @@ xg_update_horizontal_scrollbar_pos (struct frame *f,
gtk_widget_show_all (wparent);
gtk_widget_set_size_request (wscroll, width, height);
}
- gtk_widget_queue_draw (wfixed);
- gdk_window_process_all_updates ();
if (oldx != -1 && oldw > 0 && oldh > 0)
- /* Clear under old scroll bar position. This must be done after
- the gtk_widget_queue_draw and gdk_window_process_all_updates
- above. */
- x_clear_area (f,
- oldx, oldy, oldw, oldh);
+ /* Clear under old scroll bar position. */
+ x_clear_area (f, oldx, oldy, oldw, oldh);
/* GTK does not redraw until the main loop is entered again, but
if there are no X events pending we will not enter it. So we sync