0
0
mirror of https://github.com/vim/vim.git synced 2025-09-27 04:14:06 -04:00

patch 7.4.1402

Problem:    GTK 3 is not supported.
Solution:   Add GTK 3 support. (Kazunobu Kuriyama)
This commit is contained in:
Bram Moolenaar
2016-02-23 17:14:37 +01:00
parent 6bd364e084
commit 9892189d2e
20 changed files with 3086 additions and 86 deletions

View File

@@ -122,7 +122,11 @@ general_beval_cb(BalloonEval *beval, int state UNUSED)
#if !defined(FEAT_GUI_W32) || defined(PROTO)
#ifdef FEAT_GUI_GTK
# include <gdk/gdkkeysyms.h>
# if GTK_CHECK_VERSION(3,0,0)
# include <gdk/gdkkeysyms-compat.h>
# else
# include <gdk/gdkkeysyms.h>
# endif
# include <gtk/gtk.h>
#else
# include <X11/keysym.h>
@@ -164,8 +168,16 @@ static gint target_event_cb(GtkWidget *, GdkEvent *, gpointer);
static gint mainwin_event_cb(GtkWidget *, GdkEvent *, gpointer);
static void pointer_event(BalloonEval *, int, int, unsigned);
static void key_event(BalloonEval *, unsigned, int);
# if GTK_CHECK_VERSION(3,0,0)
static gboolean timeout_cb(gpointer);
# else
static gint timeout_cb(gpointer);
static gint balloon_expose_event_cb(GtkWidget *, GdkEventExpose *, gpointer);
# endif
# if GTK_CHECK_VERSION(3,0,0)
static gboolean balloon_draw_event_cb (GtkWidget *, cairo_t *, gpointer);
# else
static gint balloon_expose_event_cb (GtkWidget *, GdkEventExpose *, gpointer);
# endif
#else
static void addEventHandler(Widget, BalloonEval *);
static void removeEventHandler(BalloonEval *);
@@ -459,10 +471,16 @@ addEventHandler(GtkWidget *target, BalloonEval *beval)
* This allows us to catch events independently of the signal handlers
* in gui_gtk_x11.c.
*/
# if GTK_CHECK_VERSION(3,0,0)
g_signal_connect(G_OBJECT(target), "event",
G_CALLBACK(target_event_cb),
beval);
# else
/* Should use GTK_OBJECT() here, but that causes a lint warning... */
gtk_signal_connect((GtkObject*)(target), "event",
GTK_SIGNAL_FUNC(target_event_cb),
beval);
# endif
/*
* Nasty: Key press events go to the main window thus the drawing area
* will never see them. This means we have to connect to the main window
@@ -471,9 +489,15 @@ addEventHandler(GtkWidget *target, BalloonEval *beval)
if (gtk_socket_id == 0 && gui.mainwin != NULL
&& gtk_widget_is_ancestor(target, gui.mainwin))
{
# if GTK_CHECK_VERSION(3,0,0)
g_signal_connect(G_OBJECT(gui.mainwin), "event",
G_CALLBACK(mainwin_event_cb),
beval);
# else
gtk_signal_connect((GtkObject*)(gui.mainwin), "event",
GTK_SIGNAL_FUNC(mainwin_event_cb),
beval);
# endif
}
}
@@ -481,17 +505,29 @@ addEventHandler(GtkWidget *target, BalloonEval *beval)
removeEventHandler(BalloonEval *beval)
{
/* LINTED: avoid warning: dubious operation on enum */
# if GTK_CHECK_VERSION(3,0,0)
g_signal_handlers_disconnect_by_func(G_OBJECT(beval->target),
G_CALLBACK(target_event_cb),
beval);
# else
gtk_signal_disconnect_by_func((GtkObject*)(beval->target),
GTK_SIGNAL_FUNC(target_event_cb),
beval);
# endif
if (gtk_socket_id == 0 && gui.mainwin != NULL
&& gtk_widget_is_ancestor(beval->target, gui.mainwin))
{
/* LINTED: avoid warning: dubious operation on enum */
# if GTK_CHECK_VERSION(3,0,0)
g_signal_handlers_disconnect_by_func(G_OBJECT(gui.mainwin),
G_CALLBACK(mainwin_event_cb),
beval);
# else
gtk_signal_disconnect_by_func((GtkObject*)(gui.mainwin),
GTK_SIGNAL_FUNC(mainwin_event_cb),
beval);
# endif
}
}
@@ -517,7 +553,17 @@ target_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
* GDK_POINTER_MOTION_HINT_MASK is set, thus we cannot obtain
* the coordinates from the GdkEventMotion struct directly.
*/
# if GTK_CHECK_VERSION(3,0,0)
{
GdkWindow * const win = gtk_widget_get_window(widget);
GdkDisplay * const dpy = gdk_window_get_display(win);
GdkDeviceManager * const mngr = gdk_display_get_device_manager(dpy);
GdkDevice * const dev = gdk_device_manager_get_client_pointer(mngr);
gdk_window_get_device_position(win, dev , &x, &y, &state);
}
# else
gdk_window_get_pointer(widget->window, &x, &y, &state);
# endif
pointer_event(beval, x, y, (unsigned int)state);
}
else
@@ -609,8 +655,13 @@ pointer_event(BalloonEval *beval, int x, int y, unsigned state)
}
else
{
# if GTK_CHECK_VERSION(3,0,0)
beval->timerID = g_timeout_add((guint)p_bdlay,
&timeout_cb, beval);
# else
beval->timerID = gtk_timeout_add((guint32)p_bdlay,
&timeout_cb, beval);
# endif
}
}
}
@@ -647,7 +698,11 @@ key_event(BalloonEval *beval, unsigned keyval, int is_keypress)
cancelBalloon(beval);
}
# if GTK_CHECK_VERSION(3,0,0)
static gboolean
# else
static gint
# endif
timeout_cb(gpointer data)
{
BalloonEval *beval = (BalloonEval *)data;
@@ -663,6 +718,37 @@ timeout_cb(gpointer data)
return FALSE; /* don't call me again */
}
# if GTK_CHECK_VERSION(3,0,0)
static gboolean
balloon_draw_event_cb(GtkWidget *widget,
cairo_t *cr,
gpointer data UNUSED)
{
GtkStyleContext *context = NULL;
gint width = -1, height = -1;
if (widget == NULL)
return TRUE;
context = gtk_widget_get_style_context(widget);
width = gtk_widget_get_allocated_width(widget);
height = gtk_widget_get_allocated_height(widget);
gtk_style_context_save(context);
gtk_style_context_add_class(context, "tooltip");
gtk_style_context_set_state(context, GTK_STATE_FLAG_NORMAL);
cairo_save(cr);
gtk_render_frame(context, cr, 0, 0, width, height);
gtk_render_background(context, cr, 0, 0, width, height);
cairo_restore(cr);
gtk_style_context_restore(context);
return FALSE;
}
# else
static gint
balloon_expose_event_cb(GtkWidget *widget,
GdkEventExpose *event,
@@ -675,6 +761,7 @@ balloon_expose_event_cb(GtkWidget *widget,
return FALSE; /* continue emission */
}
# endif /* !GTK_CHECK_VERSION(3,0,0) */
#else /* !FEAT_GUI_GTK */
@@ -957,8 +1044,37 @@ set_printable_label_text(GtkLabel *label, char_u *text)
aep = syn_gui_attr2entry(hl_attr(HLF_8));
pixel = (aep != NULL) ? aep->ae_u.gui.fg_color : INVALCOLOR;
if (pixel != INVALCOLOR)
# if GTK_CHECK_VERSION(3,0,0)
{
GdkVisual * const visual = gtk_widget_get_visual(gui.drawarea);
if (visual == NULL)
{
color.red = 0;
color.green = 0;
color.blue = 0;
}
else
{
guint32 r_mask, g_mask, b_mask;
gint r_shift, g_shift, b_shift;
gdk_visual_get_red_pixel_details(visual, &r_mask, &r_shift,
NULL);
gdk_visual_get_green_pixel_details(visual, &g_mask, &g_shift,
NULL);
gdk_visual_get_blue_pixel_details(visual, &b_mask, &b_shift,
NULL);
color.red = ((pixel & r_mask) >> r_shift) / 255.0 * 65535;
color.green = ((pixel & g_mask) >> g_shift) / 255.0 * 65535;
color.blue = ((pixel & b_mask) >> b_shift) / 255.0 * 65535;
}
}
# else
gdk_colormap_query_color(gtk_widget_get_colormap(gui.drawarea),
(unsigned long)pixel, &color);
# endif
pdest = buf;
p = text;
@@ -1059,8 +1175,10 @@ drawBalloon(BalloonEval *beval)
screen_w = gdk_screen_width();
screen_h = gdk_screen_height();
# endif
# if !GTK_CHECK_VERSION(3,0,0)
gtk_widget_ensure_style(beval->balloonShell);
gtk_widget_ensure_style(beval->balloonLabel);
# endif
set_printable_label_text(GTK_LABEL(beval->balloonLabel), beval->msg);
/*
@@ -1081,10 +1199,18 @@ drawBalloon(BalloonEval *beval)
MAX(20, screen_w - 20)));
/* Calculate the balloon's width and height. */
# if GTK_CHECK_VERSION(3,0,0)
gtk_widget_get_preferred_size(beval->balloonShell, &requisition, NULL);
# else
gtk_widget_size_request(beval->balloonShell, &requisition);
# endif
/* Compute position of the balloon area */
# if GTK_CHECK_VERSION(3,0,0)
gdk_window_get_origin(gtk_widget_get_window(beval->target), &x, &y);
# else
gdk_window_get_origin(beval->target->window, &x, &y);
# endif
x += beval->x;
y += beval->y;
@@ -1099,7 +1225,11 @@ drawBalloon(BalloonEval *beval)
y = CLAMP(y + y_offset, 0, MAX(0, screen_h - requisition.height));
/* Show the balloon */
# if GTK_CHECK_VERSION(3,0,0)
gtk_window_move(GTK_WINDOW(beval->balloonShell), x, y);
# else
gtk_widget_set_uposition(beval->balloonShell, x, y);
# endif
gtk_widget_show(beval->balloonShell);
beval->showState = ShS_SHOWING;
@@ -1126,7 +1256,11 @@ cancelBalloon(BalloonEval *beval)
if (beval->timerID != 0)
{
# if GTK_CHECK_VERSION(3,0,0)
g_source_remove(beval->timerID);
# else
gtk_timeout_remove(beval->timerID);
# endif
beval->timerID = 0;
}
beval->showState = ShS_NEUTRAL;
@@ -1138,17 +1272,42 @@ createBalloonEvalWindow(BalloonEval *beval)
beval->balloonShell = gtk_window_new(GTK_WINDOW_POPUP);
gtk_widget_set_app_paintable(beval->balloonShell, TRUE);
# if GTK_CHECK_VERSION(3,0,0)
gtk_window_set_resizable(GTK_WINDOW(beval->balloonShell), FALSE);
# else
gtk_window_set_policy(GTK_WINDOW(beval->balloonShell), FALSE, FALSE, TRUE);
# endif
gtk_widget_set_name(beval->balloonShell, "gtk-tooltips");
# if GTK_CHECK_VERSION(3,0,0)
gtk_container_set_border_width(GTK_CONTAINER(beval->balloonShell), 4);
# else
gtk_container_border_width(GTK_CONTAINER(beval->balloonShell), 4);
# endif
# if GTK_CHECK_VERSION(3,0,0)
g_signal_connect(G_OBJECT(beval->balloonShell), "draw",
G_CALLBACK(balloon_draw_event_cb), NULL);
# else
gtk_signal_connect((GtkObject*)(beval->balloonShell), "expose_event",
GTK_SIGNAL_FUNC(balloon_expose_event_cb), NULL);
# endif
beval->balloonLabel = gtk_label_new(NULL);
gtk_label_set_line_wrap(GTK_LABEL(beval->balloonLabel), FALSE);
gtk_label_set_justify(GTK_LABEL(beval->balloonLabel), GTK_JUSTIFY_LEFT);
# if GTK_CHECK_VERSION(3,16,0)
gtk_label_set_xalign(GTK_LABEL(beval->balloonLabel), 0.5);
gtk_label_set_yalign(GTK_LABEL(beval->balloonLabel), 0.5);
# elif GTK_CHECK_VERSION(3,14,0)
GValue align_val = G_VALUE_INIT;
g_value_init(&align_val, G_TYPE_FLOAT);
g_value_set_float(&align_val, 0.5);
g_object_set_property(G_OBJECT(beval->balloonLabel), "xalign", &align_val);
g_object_set_property(G_OBJECT(beval->balloonLabel), "yalign", &align_val);
g_value_unset(&align_val);
# else
gtk_misc_set_alignment(GTK_MISC(beval->balloonLabel), 0.5f, 0.5f);
# endif
gtk_widget_set_name(beval->balloonLabel, "vim-balloon-label");
gtk_widget_show(beval->balloonLabel);