diff options
-rw-r--r-- | runtime/doc/eval.txt | 1 | ||||
-rw-r--r-- | runtime/doc/gui.txt | 11 | ||||
-rw-r--r-- | runtime/doc/gui_x11.txt | 10 | ||||
-rwxr-xr-x | src/auto/configure | 264 | ||||
-rw-r--r-- | src/channel.c | 33 | ||||
-rw-r--r-- | src/config.h.in | 3 | ||||
-rw-r--r-- | src/configure.in | 78 | ||||
-rw-r--r-- | src/eval.c | 4 | ||||
-rw-r--r-- | src/gui.h | 7 | ||||
-rw-r--r-- | src/gui_beval.c | 163 | ||||
-rw-r--r-- | src/gui_beval.h | 6 | ||||
-rw-r--r-- | src/gui_gtk.c | 747 | ||||
-rw-r--r-- | src/gui_gtk_f.c | 390 | ||||
-rw-r--r-- | src/gui_gtk_f.h | 19 | ||||
-rw-r--r-- | src/gui_gtk_x11.c | 1339 | ||||
-rw-r--r-- | src/if_mzsch.c | 16 | ||||
-rw-r--r-- | src/mbyte.c | 23 | ||||
-rw-r--r-- | src/netbeans.c | 44 | ||||
-rw-r--r-- | src/structs.h | 2 | ||||
-rw-r--r-- | src/version.c | 14 |
20 files changed, 3087 insertions, 87 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 022a5da7a5..abc022d392 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -7315,6 +7315,7 @@ gui_athena Compiled with Athena GUI. gui_gnome Compiled with Gnome support (gui_gtk is also defined). gui_gtk Compiled with GTK+ GUI (any version). gui_gtk2 Compiled with GTK+ 2 GUI (gui_gtk is also defined). +gui_gtk3 Compiled with GTK+ 3 GUI (gui_gtk is also defined). gui_mac Compiled with Macintosh GUI. gui_motif Compiled with Motif GUI. gui_photon Compiled with Photon GUI. diff --git a/runtime/doc/gui.txt b/runtime/doc/gui.txt index d77976330b..520eba910b 100644 --- a/runtime/doc/gui.txt +++ b/runtime/doc/gui.txt @@ -25,7 +25,7 @@ Other GUI documentation: First you must make sure you actually have a version of Vim with the GUI code included. You can check this with the ":version" command, it says "with xxx -GUI", where "xxx" is X11-Motif, X11-Athena, Photon, GTK, GTK2, etc., or +GUI", where "xxx" is X11-Motif, X11-Athena, Photon, GTK2, GTK3, etc., or "MS-Windows 32 bit GUI version". How to start the GUI depends on the system used. Mostly you can run the @@ -514,11 +514,14 @@ a menu entry. Hit <Enter> to execute it. Hit <Esc> if you want to cancel. This does require the |+menu| feature enabled at compile time. *tear-off-menus* -GTK+ and Motif support Tear-off menus. These are sort of sticky menus or +GTK+ 2 and Motif support Tear-off menus. These are sort of sticky menus or pop-up menus that are present all the time. If the resizing does not work correctly, this may be caused by using something like "Vim*geometry" in the defaults. Use "Vim.geometry" instead. +As to GTK+ 3, tear-off menus have been deprecated since GTK+ 3.4. +Accordingly, they are disabled if gvim is linked against GTK+ 3.4 or later. + The Win32 GUI version emulates Motif's tear-off menus. Actually, a Motif user will spot the differences easily, but hopefully they're just as useful. You can also use the |:tearoff| command together with |hidden-menus| to create @@ -650,8 +653,8 @@ When no or zero priority is given, 500 is used. The priority for the PopUp menu is not used. The Help menu will be placed on the far right side of the menu bar on systems -which support this (Motif and GTK+). For GTK+ 2, this is not done anymore -because right-aligning the Help menu is now discouraged UI design. +which support this (Motif and GTK+). For GTK+ 2 and 3, this is not done +anymore because right-aligning the Help menu is now discouraged UI design. You can use a priority higher than 9999, to make it go after the Help menu, but that is non-standard and is discouraged. The highest possible priority is diff --git a/runtime/doc/gui_x11.txt b/runtime/doc/gui_x11.txt index f085e2f2cb..605b998af4 100644 --- a/runtime/doc/gui_x11.txt +++ b/runtime/doc/gui_x11.txt @@ -369,6 +369,16 @@ Write this in the file ~/.gtkrc and it will be used by GTK+. For GTK+ 2 you might have to use the file ~/.gtkrc-2.0 instead, depending on your distribution. +For GTK+ 3, an effect similar to the above can be obtained by adding the +following snippet of CSS code to $XDG_HOME_DIR/gtk-3.0/gtk.css (usually, +$HOME/.config/gtk-3.0/gtk.css): + > + .tooltip { + background-color: #ffffcc; + color: #000000; + } +< + Using Vim as a GTK+ plugin *gui-gtk-socketid* When the GTK+ version of Vim starts up normally, it creates its own top level diff --git a/src/auto/configure b/src/auto/configure index 69aec67c65..1b3b0c70fc 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -821,6 +821,7 @@ with_x enable_gui enable_gtk2_check enable_gnome_check +enable_gtk3_check enable_motif_check enable_athena_check enable_nextaw_check @@ -1481,9 +1482,10 @@ Optional Features: --enable-hangulinput Include Hangul input support. --enable-xim Include XIM input support. --enable-fontset Include X fontset output support. - --enable-gui=OPTS X11 GUI default=auto OPTS=auto/no/gtk2/gnome2/motif/athena/neXtaw/photon/carbon + --enable-gui=OPTS X11 GUI default=auto OPTS=auto/no/gtk2/gnome2/gtk3/motif/athena/neXtaw/photon/carbon --enable-gtk2-check If auto-select GUI, check for GTK+ 2 default=yes --enable-gnome-check If GTK GUI, check for GNOME default=no + --enable-gtk3-check If auto-select GUI, check for GTK+ 3 default=yes --enable-motif-check If auto-select GUI, check for Motif default=yes --enable-athena-check If auto-select GUI, check for Athena default=yes --enable-nextaw-check If auto-select GUI, check for neXtaw default=yes @@ -4355,7 +4357,7 @@ fi if test "x$CARBON" = "xyes"; then - if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk2; then + if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk2 -a "X$enable_gui" != Xgtk3; then with_x=no fi fi @@ -8606,6 +8608,9 @@ $as_echo "GTK+ 2.x GUI support" >&6; } $as_echo "GNOME 2.x GUI support" >&6; } SKIP_GNOME= SKIP_GTK2=;; + gtk3) { $as_echo "$as_me:${as_lineno-$LINENO}: result: GTK+ 3.x GUI support" >&5 +$as_echo "GTK+ 3.x GUI support" >&6; } + SKIP_GTK3=;; motif) { $as_echo "$as_me:${as_lineno-$LINENO}: result: Motif GUI support" >&5 $as_echo "Motif GUI support" >&6; } SKIP_MOTIF=;; @@ -8657,6 +8662,23 @@ $as_echo "$enable_gnome_check" >&6; } fi fi +if test "x$SKIP_GTK3" != "xYES" -a "$enable_gui_canon" != "gtk3"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether or not to look for GTK+ 3" >&5 +$as_echo_n "checking whether or not to look for GTK+ 3... " >&6; } + # Check whether --enable-gtk3-check was given. +if test "${enable_gtk3_check+set}" = set; then : + enableval=$enable_gtk3_check; +else + enable_gtk3_check="yes" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_gtk3_check" >&5 +$as_echo "$enable_gtk3_check" >&6; } + if test "x$enable_gtk3_check" = "xno"; then + SKIP_GTK3=YES + fi +fi + if test "x$SKIP_MOTIF" != "xYES" -a "$enable_gui_canon" != "motif"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether or not to look for Motif" >&5 $as_echo_n "checking whether or not to look for Motif... " >&6; } @@ -8831,13 +8853,13 @@ fi if test "X$GTK_CONFIG" != "Xno" -o "X$PKG_CONFIG" != "Xno"; then { - min_gtk_version=2.2.0 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK - version >= $min_gtk_version" >&5 -$as_echo_n "checking for GTK - version >= $min_gtk_version... " >&6; } no_gtk="" if (test "X$SKIP_GTK2" != "XYES" -a "X$PKG_CONFIG" != "Xno") \ && $PKG_CONFIG --exists gtk+-2.0; then { + min_gtk_version=2.2.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK - version >= $min_gtk_version" >&5 +$as_echo_n "checking for GTK - version >= $min_gtk_version... " >&6; } GTK_CFLAGS=`$PKG_CONFIG --cflags gtk+-2.0` GTK_LIBDIR=`$PKG_CONFIG --libs-only-L gtk+-2.0` GTK_LIBS=`$PKG_CONFIG --libs gtk+-2.0` @@ -8848,6 +8870,23 @@ $as_echo_n "checking for GTK - version >= $min_gtk_version... " >&6; } gtk_micro_version=`$PKG_CONFIG --modversion gtk+-2.0 | \ sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'` } + elif (test "X$SKIP_GTK3" != "XYES" -a "X$PKG_CONFIG" != "Xno") \ + && $PKG_CONFIG --exists gtk+-3.0; then + { + min_gtk_version=2.2.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK - version >= $min_gtk_version" >&5 +$as_echo_n "checking for GTK - version >= $min_gtk_version... " >&6; } + + GTK_CFLAGS=`$PKG_CONFIG --cflags gtk+-3.0` + GTK_LIBDIR=`$PKG_CONFIG --libs-only-L gtk+-3.0` + GTK_LIBS=`$PKG_CONFIG --libs gtk+-3.0` + gtk_major_version=`$PKG_CONFIG --modversion gtk+-3.0 | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'` + gtk_minor_version=`$PKG_CONFIG --modversion gtk+-3.0 | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'` + gtk_micro_version=`$PKG_CONFIG --modversion gtk+-3.0 | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'` + } else no_gtk=yes fi @@ -8943,6 +8982,7 @@ $as_echo "no" >&6; } rm -f conf.gtktest if test "x$GTK_CFLAGS" != "x"; then + SKIP_GTK3=YES SKIP_ATHENA=YES SKIP_NEXTAW=YES SKIP_MOTIF=YES @@ -9044,6 +9084,218 @@ $as_echo "not found" >&6; } fi fi + +if test -z "$SKIP_GTK3"; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking --disable-gtktest argument" >&5 +$as_echo_n "checking --disable-gtktest argument... " >&6; } + # Check whether --enable-gtktest was given. +if test "${enable_gtktest+set}" = set; then : + enableval=$enable_gtktest; +else + enable_gtktest=yes +fi + + if test "x$enable_gtktest" = "xyes" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test enabled" >&5 +$as_echo "gtk test enabled" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test disabled" >&5 +$as_echo "gtk test disabled" >&6; } + fi + + if test "X$PKG_CONFIG" = "X"; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi + + if test "x$PKG_CONFIG" != "xno"; then + + if test "X$GTK_CONFIG" != "Xno" -o "X$PKG_CONFIG" != "Xno"; then + { + no_gtk="" + if (test "X$SKIP_GTK2" != "XYES" -a "X$PKG_CONFIG" != "Xno") \ + && $PKG_CONFIG --exists gtk+-2.0; then + { + min_gtk_version=3.0.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK - version >= $min_gtk_version" >&5 +$as_echo_n "checking for GTK - version >= $min_gtk_version... " >&6; } + GTK_CFLAGS=`$PKG_CONFIG --cflags gtk+-2.0` + GTK_LIBDIR=`$PKG_CONFIG --libs-only-L gtk+-2.0` + GTK_LIBS=`$PKG_CONFIG --libs gtk+-2.0` + gtk_major_version=`$PKG_CONFIG --modversion gtk+-2.0 | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'` + gtk_minor_version=`$PKG_CONFIG --modversion gtk+-2.0 | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'` + gtk_micro_version=`$PKG_CONFIG --modversion gtk+-2.0 | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'` + } + elif (test "X$SKIP_GTK3" != "XYES" -a "X$PKG_CONFIG" != "Xno") \ + && $PKG_CONFIG --exists gtk+-3.0; then + { + min_gtk_version=3.0.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK - version >= $min_gtk_version" >&5 +$as_echo_n "checking for GTK - version >= $min_gtk_version... " >&6; } + + GTK_CFLAGS=`$PKG_CONFIG --cflags gtk+-3.0` + GTK_LIBDIR=`$PKG_CONFIG --libs-only-L gtk+-3.0` + GTK_LIBS=`$PKG_CONFIG --libs gtk+-3.0` + gtk_major_version=`$PKG_CONFIG --modversion gtk+-3.0 | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'` + gtk_minor_version=`$PKG_CONFIG --modversion gtk+-3.0 | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'` + gtk_micro_version=`$PKG_CONFIG --modversion gtk+-3.0 | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'` + } + else + no_gtk=yes + fi + + if test "x$enable_gtktest" = "xyes" -a "x$no_gtk" = "x"; then + { + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $GTK_CFLAGS" + LIBS="$LIBS $GTK_LIBS" + + rm -f conf.gtktest + if test "$cross_compiling" = yes; then : + echo $ac_n "cross compiling; assumed OK... $ac_c" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <gtk/gtk.h> +#include <stdio.h> +#if STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#endif + +int +main () +{ +int major, minor, micro; +char *tmp_version; + +system ("touch conf.gtktest"); + +/* HP/UX 9 (%@#!) writes to sscanf strings */ +tmp_version = g_strdup("$min_gtk_version"); +if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_gtk_version"); + exit(1); + } + +if ((gtk_major_version > major) || + ((gtk_major_version == major) && (gtk_minor_version > minor)) || + ((gtk_major_version == major) && (gtk_minor_version == minor) && + (gtk_micro_version >= micro))) +{ + return 0; +} +return 1; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + no_gtk=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + } + fi + if test "x$no_gtk" = x ; then + if test "x$enable_gtktest" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes; found version $gtk_major_version.$gtk_minor_version.$gtk_micro_version" >&5 +$as_echo "yes; found version $gtk_major_version.$gtk_minor_version.$gtk_micro_version" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found version $gtk_major_version.$gtk_minor_version.$gtk_micro_version" >&5 +$as_echo "found version $gtk_major_version.$gtk_minor_version.$gtk_micro_version" >&6; } + fi + GUI_LIB_LOC="$GTK_LIBDIR" + GTK_LIBNAME="$GTK_LIBS" + GUI_INC_LOC="$GTK_CFLAGS" + else + { + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + GTK_CFLAGS="" + GTK_LIBS="" + : + } + fi + } + else + GTK_CFLAGS="" + GTK_LIBS="" + : + fi + + + rm -f conf.gtktest + + if test "x$GTK_CFLAGS" != "x"; then + SKIP_GTK2=YES + SKIP_GNOME=YES + SKIP_ATHENA=YES + SKIP_NEXTAW=YES + SKIP_MOTIF=YES + GUITYPE=GTK + + $as_echo "#define HAVE_GTK_MULTIHEAD 1" >>confdefs.h + + $as_echo "#define USE_GTK3 1" >>confdefs.h + + fi + fi +fi + if test "x$GUITYPE" = "xGTK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of Gdk-Pixbuf" >&5 $as_echo_n "checking version of Gdk-Pixbuf... " >&6; } @@ -9546,7 +9798,7 @@ done fi -if test -z "$SKIP_ATHENA" -o -z "$SKIP_NEXTAW" -o -z "$SKIP_MOTIF" -o -z "$SKIP_GTK2"; then +if test -z "$SKIP_ATHENA" -o -z "$SKIP_NEXTAW" -o -z "$SKIP_MOTIF" -o -z "$SKIP_GTK2" -o -z "$SKIP_GTK3"; then cppflags_save=$CPPFLAGS CPPFLAGS="$CPPFLAGS $X_CFLAGS" for ac_header in X11/xpm.h X11/Sunkeysym.h diff --git a/src/channel.c b/src/channel.c index e9068fee5e..c59758d853 100644 --- a/src/channel.c +++ b/src/channel.c @@ -361,6 +361,17 @@ messageFromNetbeans(XtPointer clientData, #endif #ifdef FEAT_GUI_GTK +# if GTK_CHECK_VERSION(3,0,0) + static gboolean +messageFromNetbeans(GIOChannel *unused1 UNUSED, + GIOCondition unused2 UNUSED, + gpointer clientData) +{ + channel_read_fd(GPOINTER_TO_INT(clientData)); + return TRUE; /* Return FALSE instead in case the event source is to + * be removed after this function returns. */ +} +# else static void messageFromNetbeans(gpointer clientData, gint unused1 UNUSED, @@ -368,6 +379,7 @@ messageFromNetbeans(gpointer clientData, { channel_read_fd((int)(long)clientData); } +# endif #endif static void @@ -388,12 +400,27 @@ channel_gui_register_one(channel_T *channel, int part) /* Tell gdk we are interested in being called when there * is input on the editor connection socket. */ if (channel->ch_part[part].ch_inputHandler == 0) +# if GTK_CHECK_VERSION(3,0,0) + { + GIOChannel *chnnl = g_io_channel_unix_new( + (gint)channel->ch_part[part].ch_fd); + + channel->ch_part[part].ch_inputHandler = g_io_add_watch( + chnnl, + G_IO_IN|G_IO_HUP|G_IO_ERR|G_IO_PRI, + messageFromNetbeans, + GINT_TO_POINTER(channel->ch_part[part].ch_fd)); + + g_io_channel_unref(chnnl); + } +# else channel->ch_part[part].ch_inputHandler = gdk_input_add( (gint)channel->ch_part[part].ch_fd, (GdkInputCondition) ((int)GDK_INPUT_READ + (int)GDK_INPUT_EXCEPTION), messageFromNetbeans, (gpointer)(long)channel->ch_part[part].ch_fd); +# endif # else # ifdef FEAT_GUI_W32 /* Tell Windows we are interested in receiving message when there @@ -457,7 +484,11 @@ channel_gui_unregister(channel_T *channel) # ifdef FEAT_GUI_GTK if (channel->ch_part[part].ch_inputHandler != 0) { +# if GTK_CHECK_VERSION(3,0,0) + g_source_remove(channel->ch_part[part].ch_inputHandler); +# else gdk_input_remove(channel->ch_part[part].ch_inputHandler); +# endif channel->ch_part[part].ch_inputHandler = 0; } # else @@ -606,7 +637,7 @@ channel_open( fd_set wfds; #if defined(__APPLE__) && __APPLE__ == 1 # define PASS_RFDS - fd_set rfds; + fd_set rfds; FD_ZERO(&rfds); FD_SET(sd, &rfds); diff --git a/src/config.h.in b/src/config.h.in index 8e115f5f16..fd45c7332b 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -460,3 +460,6 @@ /* Define if GResource is used to load icons */ #undef USE_GRESOURCE + +/* Define if GTK+ GUI is to be linked against GTK+ 3 */ +#undef USE_GTK3 diff --git a/src/configure.in b/src/configure.in index 9f19c137b6..930278c7de 100644 --- a/src/configure.in +++ b/src/configure.in @@ -213,7 +213,7 @@ if test "`(uname) 2>/dev/null`" = Darwin; then dnl or Motif, Athena or GTK GUI is used. AC_CHECK_HEADER(Carbon/Carbon.h, CARBON=yes) if test "x$CARBON" = "xyes"; then - if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk2; then + if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk2 -a "X$enable_gui" != Xgtk3; then with_x=no fi fi @@ -2198,7 +2198,7 @@ test "x$with_x" = xno -a "x$MACOSX" != "xyes" -a "x$QNX" != "xyes" && enable_gui AC_MSG_CHECKING(--enable-gui argument) AC_ARG_ENABLE(gui, - [ --enable-gui[=OPTS] X11 GUI [default=auto] [OPTS=auto/no/gtk2/gnome2/motif/athena/neXtaw/photon/carbon]], , enable_gui="auto") + [ --enable-gui[=OPTS] X11 GUI [default=auto] [OPTS=auto/no/gtk2/gnome2/gtk3/motif/athena/neXtaw/photon/carbon]], , enable_gui="auto") dnl Canonicalize the --enable-gui= argument so that it can be easily compared. dnl Do not use character classes for portability with old tools. @@ -2256,6 +2256,8 @@ else gnome2) AC_MSG_RESULT(GNOME 2.x GUI support) SKIP_GNOME= SKIP_GTK2=;; + gtk3) AC_MSG_RESULT(GTK+ 3.x GUI support) + SKIP_GTK3=;; motif) AC_MSG_RESULT(Motif GUI support) SKIP_MOTIF=;; athena) AC_MSG_RESULT(Athena GUI support) @@ -2291,6 +2293,17 @@ if test "x$SKIP_GNOME" != "xYES" -a "$enable_gui_canon" != "gnome2"; then fi fi +if test "x$SKIP_GTK3" != "xYES" -a "$enable_gui_canon" != "gtk3"; then + AC_MSG_CHECKING(whether or not to look for GTK+ 3) + AC_ARG_ENABLE(gtk3-check, + [ --enable-gtk3-check If auto-select GUI, check for GTK+ 3 [default=yes]], + , enable_gtk3_check="yes") + AC_MSG_RESULT($enable_gtk3_check) + if test "x$enable_gtk3_check" = "xno"; then + SKIP_GTK3=YES + fi +fi + if test "x$SKIP_MOTIF" != "xYES" -a "$enable_gui_canon" != "motif"; then AC_MSG_CHECKING(whether or not to look for Motif) AC_ARG_ENABLE(motif-check, @@ -2379,12 +2392,12 @@ AC_DEFUN(AM_PATH_GTK, [ if test "X$GTK_CONFIG" != "Xno" -o "X$PKG_CONFIG" != "Xno"; then { - min_gtk_version=ifelse([$1], ,2.2.0,$1) - AC_MSG_CHECKING(for GTK - version >= $min_gtk_version) no_gtk="" if (test "X$SKIP_GTK2" != "XYES" -a "X$PKG_CONFIG" != "Xno") \ && $PKG_CONFIG --exists gtk+-2.0; then { + min_gtk_version=ifelse([$1], ,2.2.0,$1) + AC_MSG_CHECKING(for GTK - version >= $min_gtk_version) dnl We should be using PKG_CHECK_MODULES() instead of this hack. dnl But I guess the dependency on pkgconfig.m4 is not wanted or dnl something like that. @@ -2398,6 +2411,22 @@ AC_DEFUN(AM_PATH_GTK, gtk_micro_version=`$PKG_CONFIG --modversion gtk+-2.0 | \ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` } + elif (test "X$SKIP_GTK3" != "XYES" -a "X$PKG_CONFIG" != "Xno") \ + && $PKG_CONFIG --exists gtk+-3.0; then + { + min_gtk_version=ifelse([$1], ,3.0.0,$1) + AC_MSG_CHECKING(for GTK - version >= $min_gtk_version) + + GTK_CFLAGS=`$PKG_CONFIG --cflags gtk+-3.0` + GTK_LIBDIR=`$PKG_CONFIG --libs-only-L gtk+-3.0` + GTK_LIBS=`$PKG_CONFIG --libs gtk+-3.0` + gtk_major_version=`$PKG_CONFIG --modversion gtk+-3.0 | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` + gtk_minor_version=`$PKG_CONFIG --modversion gtk+-3.0 | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` + gtk_micro_version=`$PKG_CONFIG --modversion gtk+-3.0 | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` + } else no_gtk=yes fi @@ -2573,6 +2602,7 @@ if test -z "$SKIP_GTK2"; then GTK_LIBNAME="$GTK_LIBS" GUI_INC_LOC="$GTK_CFLAGS"], ) if test "x$GTK_CFLAGS" != "x"; then + SKIP_GTK3=YES SKIP_ATHENA=YES SKIP_NEXTAW=YES SKIP_MOTIF=YES @@ -2601,6 +2631,44 @@ if test -z "$SKIP_GTK2"; then fi fi + +dnl --------------------------------------------------------------------------- +dnl Check for GTK3. +dnl --------------------------------------------------------------------------- +if test -z "$SKIP_GTK3"; then + + AC_MSG_CHECKING(--disable-gtktest argument) + AC_ARG_ENABLE(gtktest, [ --disable-gtktest Do not try to compile and run a test GTK program], + , enable_gtktest=yes) + if test "x$enable_gtktest" = "xyes" ; then + AC_MSG_RESULT(gtk test enabled) + else + AC_MSG_RESULT(gtk test disabled) + fi + + if test "X$PKG_CONFIG" = "X"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + + if test "x$PKG_CONFIG" != "xno"; then + AM_PATH_GTK(3.0.0, + [GUI_LIB_LOC="$GTK_LIBDIR" + GTK_LIBNAME="$GTK_LIBS" + GUI_INC_LOC="$GTK_CFLAGS"], ) + if test "x$GTK_CFLAGS" != "x"; then + SKIP_GTK2=YES + SKIP_GNOME=YES + SKIP_ATHENA=YES + SKIP_NEXTAW=YES + SKIP_MOTIF=YES + GUITYPE=GTK + AC_SUBST(GTK_LIBNAME) + AC_DEFINE(HAVE_GTK_MULTIHEAD) + AC_DEFINE(USE_GTK3) + fi + fi +fi + dnl Check the version of Gdk-Pixbuf. If the version is 2.31 or later and dnl glib-compile-resources is found in PATH, use GResource. if test "x$GUITYPE" = "xGTK"; then @@ -2823,7 +2891,7 @@ if test "$enable_xsmp" = "yes"; then fi -if test -z "$SKIP_ATHENA" -o -z "$SKIP_NEXTAW" -o -z "$SKIP_MOTIF" -o -z "$SKIP_GTK2"; then +if test -z "$SKIP_ATHENA" -o -z "$SKIP_NEXTAW" -o -z "$SKIP_MOTIF" -o -z "$SKIP_GTK2" -o -z "$SKIP_GTK3"; then dnl Check for X11/xpm.h and X11/Sunkeysym.h with the GUI include path cppflags_save=$CPPFLAGS CPPFLAGS="$CPPFLAGS $X_CFLAGS" diff --git a/src/eval.c b/src/eval.c index 3b1172ecd8..1471568184 100644 --- a/src/eval.c +++ b/src/eval.c @@ -13671,7 +13671,11 @@ f_has(typval_T *argvars, typval_T *rettv) #endif #ifdef FEAT_GUI_GTK "gui_gtk", +# ifdef USE_GTK3 + "gui_gtk3", +# else "gui_gtk2", +# endif #endif #ifdef FEAT_GUI_GNOME "gui_gnome", @@ -359,7 +359,9 @@ typedef struct Gui #endif #ifdef FEAT_GUI_GTK +# ifndef USE_GTK3 int visibility; /* Is shell partially/fully obscured? */ +# endif GdkCursor *blank_pointer; /* Blank pointer */ /* X Resources */ @@ -381,7 +383,12 @@ typedef struct Gui GdkColor *fgcolor; /* GDK-styled foreground color */ GdkColor *bgcolor; /* GDK-styled background color */ GdkColor *spcolor; /* GDK-styled special color */ +# ifdef USE_GTK3 + cairo_surface_t *surface; /* drawarea surface */ + gboolean by_signal; /* cause of draw operation */ +# else GdkGC *text_gc; /* cached GC for normal text */ +# endif PangoContext *text_context; /* the context used for all text */ PangoFont *ascii_font; /* cached font for ASCII strings */ PangoGlyphString *ascii_glyphs; /* cached code point -> glyph map */ diff --git a/src/gui_beval.c b/src/gui_beval.c index e96e67d3fd..258ba8aeb7 100644 --- a/src/gui_beval.c +++ b/src/gui_beval.c @@ -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) |