To: vim_dev@googlegroups.com Subject: Patch 7.4.1402 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1402 Problem: GTK 3 is not supported. Solution: Add GTK 3 support. (Kazunobu Kuriyama) Files: runtime/doc/eval.txt, runtime/doc/gui.txt, runtime/doc/gui_x11.txt, src/auto/configure, src/channel.c, src/config.h.in, src/configure.in, src/eval.c, src/gui.h, src/gui_beval.c, src/gui_beval.h, src/gui_gtk.c, src/gui_gtk_f.c, src/gui_gtk_f.h, src/gui_gtk_x11.c, src/if_mzsch.c, src/mbyte.c, src/netbeans.c, src/structs.h, src/version.c *** ../vim-7.4.1401/runtime/doc/eval.txt 2016-02-21 20:08:19.546419633 +0100 --- runtime/doc/eval.txt 2016-02-23 16:23:03.832915204 +0100 *************** *** 7240,7245 **** --- 7315,7321 ---- 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. *** ../vim-7.4.1401/runtime/doc/gui.txt 2013-08-10 13:24:53.000000000 +0200 --- runtime/doc/gui.txt 2016-02-23 16:23:03.836915162 +0100 *************** *** 25,31 **** 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 "MS-Windows 32 bit GUI version". How to start the GUI depends on the system used. Mostly you can run the --- 25,31 ---- 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, 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 *************** *** 510,520 **** 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 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. 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 --- 514,527 ---- This does require the |+menu| feature enabled at compile time. *tear-off-menus* ! 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 *************** *** 646,653 **** 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. 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 --- 653,660 ---- 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 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 *** ../vim-7.4.1401/runtime/doc/gui_x11.txt 2013-08-10 13:24:54.000000000 +0200 --- runtime/doc/gui_x11.txt 2016-02-23 16:23:03.836915162 +0100 *************** *** 369,374 **** --- 369,384 ---- 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 *** ../vim-7.4.1401/src/auto/configure 2016-02-22 21:07:01.887474438 +0100 --- src/auto/configure 2016-02-23 16:27:54.141880227 +0100 *************** *** 821,826 **** --- 821,827 ---- enable_gui enable_gtk2_check enable_gnome_check + enable_gtk3_check enable_motif_check enable_athena_check enable_nextaw_check *************** *** 1481,1489 **** --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-gtk2-check If auto-select GUI, check for GTK+ 2 default=yes --enable-gnome-check If GTK GUI, check for GNOME default=no --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 --- 1482,1491 ---- --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/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,4361 **** 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 with_x=no fi fi --- 4357,4363 ---- 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 -a "X$enable_gui" != Xgtk3; then with_x=no fi fi *************** *** 8606,8611 **** --- 8608,8616 ---- $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,8662 **** --- 8662,8684 ---- 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,8843 **** 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 { 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` --- 8853,8865 ---- 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=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,8853 **** --- 8870,8892 ---- 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,8948 **** --- 8982,8988 ---- rm -f conf.gtktest if test "x$GTK_CFLAGS" != "x"; then + SKIP_GTK3=YES SKIP_ATHENA=YES SKIP_NEXTAW=YES SKIP_MOTIF=YES *************** *** 9044,9049 **** --- 9084,9301 ---- 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 + #include + #if STDC_HEADERS + # include + # include + #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,9552 **** fi ! if test -z "$SKIP_ATHENA" -o -z "$SKIP_NEXTAW" -o -z "$SKIP_MOTIF" -o -z "$SKIP_GTK2"; then cppflags_save=$CPPFLAGS CPPFLAGS="$CPPFLAGS $X_CFLAGS" for ac_header in X11/xpm.h X11/Sunkeysym.h --- 9798,9804 ---- fi ! 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 *** ../vim-7.4.1401/src/channel.c 2016-02-23 13:20:18.462462214 +0100 --- src/channel.c 2016-02-23 16:31:57.423337704 +0100 *************** *** 361,366 **** --- 361,377 ---- #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,373 **** --- 379,385 ---- { channel_read_fd((int)(long)clientData); } + # endif #endif static void *************** *** 388,399 **** --- 400,426 ---- /* 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,463 **** --- 484,494 ---- # 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,612 **** fd_set wfds; #if defined(__APPLE__) && __APPLE__ == 1 # define PASS_RFDS ! fd_set rfds; FD_ZERO(&rfds); FD_SET(sd, &rfds); --- 637,643 ---- fd_set wfds; #if defined(__APPLE__) && __APPLE__ == 1 # define PASS_RFDS ! fd_set rfds; FD_ZERO(&rfds); FD_SET(sd, &rfds); *** ../vim-7.4.1401/src/config.h.in 2016-01-30 23:26:28.931356949 +0100 --- src/config.h.in 2016-02-23 16:23:03.840915121 +0100 *************** *** 460,462 **** --- 460,465 ---- /* 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 *** ../vim-7.4.1401/src/configure.in 2016-02-22 21:07:01.883474479 +0100 --- src/configure.in 2016-02-23 16:23:03.840915121 +0100 *************** *** 213,219 **** 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 with_x=no fi fi --- 213,219 ---- 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 -a "X$enable_gui" != Xgtk3; then with_x=no fi fi *************** *** 2198,2204 **** 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") dnl Canonicalize the --enable-gui= argument so that it can be easily compared. dnl Do not use character classes for portability with old tools. --- 2198,2204 ---- AC_MSG_CHECKING(--enable-gui argument) AC_ARG_ENABLE(gui, ! [ --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,2261 **** --- 2256,2263 ---- 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,2296 **** --- 2293,2309 ---- 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,2390 **** [ 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 { 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. --- 2392,2403 ---- [ 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=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,2403 **** --- 2411,2432 ---- 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,2578 **** --- 2602,2608 ---- 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,2606 **** --- 2631,2674 ---- 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,2829 **** fi ! if test -z "$SKIP_ATHENA" -o -z "$SKIP_NEXTAW" -o -z "$SKIP_MOTIF" -o -z "$SKIP_GTK2"; then dnl Check for X11/xpm.h and X11/Sunkeysym.h with the GUI include path cppflags_save=$CPPFLAGS CPPFLAGS="$CPPFLAGS $X_CFLAGS" --- 2891,2897 ---- fi ! 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" *** ../vim-7.4.1401/src/eval.c 2016-02-23 14:52:31.873232295 +0100 --- src/eval.c 2016-02-23 16:31:17.715752637 +0100 *************** *** 13671,13677 **** --- 13671,13681 ---- #endif #ifdef FEAT_GUI_GTK "gui_gtk", + # ifdef USE_GTK3 + "gui_gtk3", + # else "gui_gtk2", + # endif #endif #ifdef FEAT_GUI_GNOME "gui_gnome", *** ../vim-7.4.1401/src/gui.h 2016-02-20 22:16:54.082901623 +0100 --- src/gui.h 2016-02-23 16:32:28.067017498 +0100 *************** *** 359,365 **** --- 359,367 ---- #endif #ifdef FEAT_GUI_GTK + # ifndef USE_GTK3 int visibility; /* Is shell partially/fully obscured? */ + # endif GdkCursor *blank_pointer; /* Blank pointer */ /* X Resources */ *************** *** 381,387 **** --- 383,394 ---- 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 */ *** ../vim-7.4.1401/src/gui_beval.c 2016-01-30 16:39:20.434376524 +0100 --- src/gui_beval.c 2016-02-23 16:33:12.342554870 +0100 *************** *** 122,128 **** #if !defined(FEAT_GUI_W32) || defined(PROTO) #ifdef FEAT_GUI_GTK ! # include # include #else # include --- 122,132 ---- #if !defined(FEAT_GUI_W32) || defined(PROTO) #ifdef FEAT_GUI_GTK ! # if GTK_CHECK_VERSION(3,0,0) ! # include ! # else ! # include ! # endif # include #else # include *************** *** 164,171 **** static gint mainwin_event_cb(GtkWidget *, GdkEvent *, gpointer); static void pointer_event(BalloonEval *, int, int, unsigned); static void key_event(BalloonEval *, unsigned, int); static gint timeout_cb(gpointer); ! static gint balloon_expose_event_cb(GtkWidget *, GdkEventExpose *, gpointer); #else static void addEventHandler(Widget, BalloonEval *); static void removeEventHandler(BalloonEval *); --- 168,183 ---- 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); ! # 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,468 **** --- 471,486 ---- * 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,479 **** --- 489,503 ---- 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,497 **** --- 505,533 ---- 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,523 **** --- 553,569 ---- * 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,616 **** --- 655,667 ---- } 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,653 **** --- 698,708 ---- cancelBalloon(beval); } + # if GTK_CHECK_VERSION(3,0,0) + static gboolean + # else static gint + # endif timeout_cb(gpointer data) { BalloonEval *beval = (BalloonEval *)data; *************** *** 663,668 **** --- 718,754 ---- 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,680 **** --- 761,767 ---- return FALSE; /* continue emission */ } + # endif /* !GTK_CHECK_VERSION(3,0,0) */ #else /* !FEAT_GUI_GTK */ *************** *** 957,964 **** --- 1044,1080 ---- 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,1066 **** --- 1175,1184 ---- 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,1090 **** --- 1199,1216 ---- 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,1105 **** --- 1225,1235 ---- 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,1132 **** --- 1256,1266 ---- 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,1154 **** --- 1272,1313 ---- 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); *** ../vim-7.4.1401/src/gui_beval.h 2016-01-29 23:20:35.313308119 +0100 --- src/gui_beval.h 2016-02-23 16:23:03.844915079 +0100 *************** *** 11,17 **** #define GUI_BEVAL_H #ifdef FEAT_GUI_GTK ! # include #else # if defined(FEAT_GUI_X11) # include --- 11,21 ---- #define GUI_BEVAL_H #ifdef FEAT_GUI_GTK ! # ifdef USE_GTK3 ! # include ! # else ! # include ! # endif #else # if defined(FEAT_GUI_X11) # include *** ../vim-7.4.1401/src/gui_gtk.c 2016-01-30 16:39:20.434376524 +0100 --- src/gui_gtk.c 2016-02-23 16:35:47.204936910 +0100 *************** *** 22,29 **** --- 22,38 ---- * * Best supporting actor (He helped somewhat, aesthetically speaking): * Maxime Romano + * + * Support for GTK+ 3 was added by: + * + * 2016 Kazunobu Kuriyama + * + * With the help of Marius Gedminas and the word of Bram Moolenaar, + * "Let's give this some time to mature." */ + #include "vim.h" + #ifdef FEAT_GUI_GTK # include "gui_gtk_f.h" #endif *************** *** 37,44 **** # undef MAX #endif - #include "vim.h" - #ifdef FEAT_GUI_GNOME /* Gnome redefines _() and N_(). Grrr... */ # ifdef _ --- 46,51 ---- *************** *** 63,69 **** #endif #ifdef FEAT_GUI_GTK ! # include # include # ifdef WIN3264 # include --- 70,80 ---- #endif #ifdef FEAT_GUI_GTK ! # if GTK_CHECK_VERSION(3,0,0) ! # include ! # else ! # include ! # endif # include # ifdef WIN3264 # include *************** *** 104,109 **** --- 115,184 ---- * match toolbar_names[] in menu.c! All stock icons including the "vim-*" * ones can be overridden in your gtkrc file. */ + # if GTK_CHECK_VERSION(3,10,0) + static const char * const menu_themed_names[] = + { + /* 00 */ "document-new", /* sub. GTK_STOCK_NEW */ + /* 01 */ "document-open", /* sub. GTK_STOCK_OPEN */ + /* 02 */ "document-save", /* sub. GTK_STOCK_SAVE */ + /* 03 */ "edit-undo", /* sub. GTK_STOCK_UNDO */ + /* 04 */ "edit-redo", /* sub. GTK_STOCK_REDO */ + /* 05 */ "edit-cut", /* sub. GTK_STOCK_CUT */ + /* 06 */ "edit-copy", /* sub. GTK_STOCK_COPY */ + /* 07 */ "edit-paste", /* sub. GTK_STOCK_PASTE */ + /* 08 */ "document-print", /* sub. GTK_STOCK_PRINT */ + /* 09 */ "help-browser", /* sub. GTK_STOCK_HELP */ + /* 10 */ "edit-find", /* sub. GTK_STOCK_FIND */ + # if GTK_CHECK_VERSION(3,14,0) + /* Use the file names in gui_gtk_res.xml, cutting off the extension. + * Similar changes follow. */ + /* 11 */ "stock_vim_save_all", + /* 12 */ "stock_vim_session_save", + /* 13 */ "stock_vim_session_new", + /* 14 */ "stock_vim_session_load", + # else + /* 11 */ "vim-save-all", + /* 12 */ "vim-session-save", + /* 13 */ "vim-session-new", + /* 14 */ "vim-session-load", + # endif + /* 15 */ "system-run", /* sub. GTK_STOCK_EXECUTE */ + /* 16 */ "edit-find-replace", /* sub. GTK_STOCK_FIND_AND_REPLACE */ + /* 17 */ "window-close", /* sub. GTK_STOCK_CLOSE, FIXME: fuzzy */ + # if GTK_CHECK_VERSION(3,14,0) + /* 18 */ "stock_vim_window_maximize", + /* 19 */ "stock_vim_window_minimize", + /* 20 */ "stock_vim_window_split", + /* 21 */ "stock_vim_shell", + # else + /* 18 */ "vim-window-maximize", + /* 19 */ "vim-window-minimize", + /* 20 */ "vim-window-split", + /* 21 */ "vim-shell", + # endif + /* 22 */ "go-previous", /* sub. GTK_STOCK_GO_BACK */ + /* 23 */ "go-next", /* sub. GTK_STOCK_GO_FORWARD */ + # if GTK_CHECK_VERSION(3,14,0) + /* 24 */ "stock_vim_find_help", + # else + /* 24 */ "vim-find-help", + # endif + /* 25 */ "gtk-convert", /* sub. GTK_STOCK_CONVERT */ + /* 26 */ "go-jump", /* sub. GTK_STOCK_JUMP_TO */ + # if GTK_CHECK_VERSION(3,14,0) + /* 27 */ "stock_vim_build_tags", + /* 28 */ "stock_vim_window_split_vertical", + /* 29 */ "stock_vim_window_maximize_width", + /* 30 */ "stock_vim_window_minimize_width", + # else + /* 27 */ "vim-build-tags", + /* 28 */ "vim-window-split-vertical", + /* 29 */ "vim-window-maximize-width", + /* 30 */ "vim-window-minimize-width", + # endif + /* 31 */ "application-exit", /* GTK_STOCK_QUIT */ + }; + # else /* !GTK_CHECK_VERSION(3,10,0) */ static const char * const menu_stock_ids[] = { /* 00 */ GTK_STOCK_NEW, *************** *** 139,146 **** /* 30 */ "vim-window-minimize-width", /* 31 */ GTK_STOCK_QUIT }; ! #ifdef USE_GRESOURCE typedef struct IconNames { const char *icon_name; const char *file_name; --- 214,223 ---- /* 30 */ "vim-window-minimize-width", /* 31 */ GTK_STOCK_QUIT }; + # endif /* !GTK_CHECK_VERSION(3,10,0) */ ! # ifdef USE_GRESOURCE ! # if !GTK_CHECK_VERSION(3,10,0) typedef struct IconNames { const char *icon_name; const char *file_name; *************** *** 162,170 **** { "vim-window-split-vertical", "stock_vim_window_split_vertical.png" }, { NULL, NULL } }; ! #endif ! #ifndef USE_GRESOURCE static void add_stock_icon(GtkIconFactory *factory, const char *stock_id, --- 239,248 ---- { "vim-window-split-vertical", "stock_vim_window_split_vertical.png" }, { NULL, NULL } }; ! # endif ! # endif /* USE_G_RESOURCE */ ! # ifndef USE_GRESOURCE static void add_stock_icon(GtkIconFactory *factory, const char *stock_id, *************** *** 182,188 **** gtk_icon_set_unref(icon_set); g_object_unref(pixbuf); } ! #endif static int lookup_menu_iconfile(char_u *iconfile, char_u *dest) --- 260,266 ---- gtk_icon_set_unref(icon_set); g_object_unref(pixbuf); } ! # endif static int lookup_menu_iconfile(char_u *iconfile, char_u *dest) *************** *** 214,219 **** --- 292,343 ---- load_menu_iconfile(char_u *name, GtkIconSize icon_size) { GtkWidget *image = NULL; + # if GTK_CHECK_VERSION(3,10,0) + int pixel_size = -1; + + switch (icon_size) + { + case GTK_ICON_SIZE_MENU: + pixel_size = 16; + break; + case GTK_ICON_SIZE_SMALL_TOOLBAR: + pixel_size = 16; + break; + case GTK_ICON_SIZE_LARGE_TOOLBAR: + pixel_size = 24; + break; + case GTK_ICON_SIZE_BUTTON: + pixel_size = 16; + break; + case GTK_ICON_SIZE_DND: + pixel_size = 32; + break; + case GTK_ICON_SIZE_DIALOG: + pixel_size = 48; + break; + case GTK_ICON_SIZE_INVALID: + /* FALLTHROUGH */ + default: + pixel_size = 0; + break; + } + + if (pixel_size > 0 || pixel_size == -1) + { + GdkPixbuf * const pixbuf + = gdk_pixbuf_new_from_file_at_scale((const char *)name, + pixel_size, pixel_size, TRUE, NULL); + if (pixbuf != NULL) + { + image = gtk_image_new_from_pixbuf(pixbuf); + g_object_unref(pixbuf); + } + } + if (image == NULL) + image = gtk_image_new_from_icon_name("image-missing", icon_size); + + return image; + # else /* !GTK_CHECK_VERSION(3,10,0) */ GtkIconSet *icon_set; GtkIconSource *icon_source; *************** *** 234,239 **** --- 358,364 ---- gtk_icon_set_unref(icon_set); return image; + # endif /* !GTK_CHECK_VERSION(3,10,0) */ } static GtkWidget * *************** *** 254,259 **** --- 379,395 ---- /* Still not found? Then use a builtin icon, a blank one as fallback. */ if (image == NULL) { + # if GTK_CHECK_VERSION(3,10,0) + const char *icon_name = NULL; + const int n_names = G_N_ELEMENTS(menu_themed_names); + + if (menu->iconidx >= 0 && menu->iconidx < n_names) + icon_name = menu_themed_names[menu->iconidx]; + if (icon_name == NULL) + icon_name = "image-missing"; + + image = gtk_image_new_from_icon_name(icon_name, icon_size); + # else const char *stock_id; const int n_ids = G_N_ELEMENTS(menu_stock_ids); *************** *** 263,268 **** --- 399,405 ---- stock_id = GTK_STOCK_MISSING_IMAGE; image = gtk_image_new_from_stock(stock_id, icon_size); + # endif } return image; *************** *** 288,299 **** void gui_gtk_register_stock_icons(void) { ! #ifndef USE_GRESOURCE ! # include "../pixmaps/stock_icons.h" GtkIconFactory *factory; factory = gtk_icon_factory_new(); ! # define ADD_ICON(Name, Data) add_stock_icon(factory, Name, Data, (int)sizeof(Data)) ADD_ICON("vim-build-tags", stock_vim_build_tags); ADD_ICON("vim-find-help", stock_vim_find_help); --- 425,436 ---- void gui_gtk_register_stock_icons(void) { ! # ifndef USE_GRESOURCE ! # include "../pixmaps/stock_icons.h" GtkIconFactory *factory; factory = gtk_icon_factory_new(); ! # define ADD_ICON(Name, Data) add_stock_icon(factory, Name, Data, (int)sizeof(Data)) ADD_ICON("vim-build-tags", stock_vim_build_tags); ADD_ICON("vim-find-help", stock_vim_find_help); *************** *** 309,343 **** ADD_ICON("vim-window-split", stock_vim_window_split); ADD_ICON("vim-window-split-vertical", stock_vim_window_split_vertical); ! # undef ADD_ICON ! #else ! GtkIconFactory * const factory = gtk_icon_factory_new(); const char * const path_prefix = "/org/vim/gui/icon"; IconNames *names; for (names = stock_vim_icons; names->icon_name != NULL; names++) { ! char path[MAXPATHL]; ! GdkPixbuf *pixbuf; ! vim_snprintf(path, MAXPATHL, "%s/%s", path_prefix, names->file_name); ! pixbuf = gdk_pixbuf_new_from_resource(path, NULL); ! if (pixbuf != NULL) ! { ! GtkIconSet *icon_set = gtk_icon_set_new_from_pixbuf(pixbuf); ! gtk_icon_factory_add(factory, names->icon_name, icon_set); ! gtk_icon_set_unref(icon_set); ! g_object_unref(pixbuf); ! } } ! #endif gtk_icon_factory_add_default(factory); g_object_unref(factory); } #endif /* FEAT_TOOLBAR */ - #if defined(FEAT_MENU) || defined(PROTO) /* --- 446,536 ---- ADD_ICON("vim-window-split", stock_vim_window_split); ADD_ICON("vim-window-split-vertical", stock_vim_window_split_vertical); ! # undef ADD_ICON ! ! gtk_icon_factory_add_default(factory); ! g_object_unref(factory); ! # else /* defined(USE_GRESOURCE) */ const char * const path_prefix = "/org/vim/gui/icon"; + # if GTK_CHECK_VERSION(3,14,0) + GdkScreen *screen = NULL; + GtkIconTheme *icon_theme = NULL; + + if (GTK_IS_WIDGET(gui.mainwin)) + screen = gtk_widget_get_screen(gui.mainwin); + else + screen = gdk_screen_get_default(); + icon_theme = gtk_icon_theme_get_for_screen(screen); + gtk_icon_theme_add_resource_path(icon_theme, path_prefix); + # elif GTK_CHECK_VERSION(3,0,0) IconNames *names; for (names = stock_vim_icons; names->icon_name != NULL; names++) { ! char path[MAXPATHL]; ! vim_snprintf(path, MAXPATHL, "%s/%s", path_prefix, names->file_name); ! GdkPixbuf *pixbuf = NULL; ! pixbuf = gdk_pixbuf_new_from_resource(path, NULL); ! if (pixbuf != NULL) ! { ! const gint size = MAX(gdk_pixbuf_get_width(pixbuf), ! gdk_pixbuf_get_height(pixbuf)); ! if (size > 16) ! { ! /* An icon theme is supposed to provide fixed-size ! * image files for each size, e.g., 16, 22, 24, ... ! * Naturally, in contrast to GtkIconSet, GtkIconTheme ! * won't prepare size variants for us out of a single ! * fixed-size image. ! * ! * Currently, Vim provides 24x24 images only while the ! * icon size on the menu and the toolbar is set to 16x16 ! * by default. ! * ! * Resize them by ourselves until we have our own fully ! * fledged icon theme. */ ! GdkPixbuf *src = pixbuf; ! pixbuf = gdk_pixbuf_scale_simple(src, ! 16, 16, ! GDK_INTERP_BILINEAR); ! if (pixbuf == NULL) ! pixbuf = src; ! else ! g_object_unref(src); ! } ! gtk_icon_theme_add_builtin_icon(names->icon_name, size, pixbuf); ! g_object_unref(pixbuf); ! } } ! # else /* !GTK_CHECK_VERSION(3,0.0) */ ! GtkIconFactory * const factory = gtk_icon_factory_new(); ! IconNames *names; ! ! for (names = stock_vim_icons; names->icon_name != NULL; names++) ! { ! char path[MAXPATHL]; ! GdkPixbuf *pixbuf; ! ! vim_snprintf(path, MAXPATHL, "%s/%s", path_prefix, names->file_name); ! pixbuf = gdk_pixbuf_new_from_resource(path, NULL); ! if (pixbuf != NULL) ! { ! GtkIconSet *icon_set = gtk_icon_set_new_from_pixbuf(pixbuf); ! gtk_icon_factory_add(factory, names->icon_name, icon_set); ! gtk_icon_set_unref(icon_set); ! g_object_unref(pixbuf); ! } ! } ! gtk_icon_factory_add_default(factory); g_object_unref(factory); + # endif /* !GTK_CHECK_VERSION(3,0,0) */ + # endif /* defined(USE_GRESOURCE) */ } #endif /* FEAT_TOOLBAR */ #if defined(FEAT_MENU) || defined(PROTO) /* *************** *** 408,414 **** --- 601,612 ---- * changes to Vim's menu system. Not to mention that all the translations * had to be updated. */ menu->id = gtk_menu_item_new(); + # if GTK_CHECK_VERSION(3,2,0) + box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 20); + gtk_box_set_homogeneous(GTK_BOX(box), FALSE); + # else box = gtk_hbox_new(FALSE, 20); + # endif use_mnemonic = (p_wak[0] != 'n' || !GTK_IS_MENU_BAR(parent_widget)); text = translate_mnemonic_tag(menu->name, use_mnemonic); *************** *** 465,474 **** --- 663,679 ---- gtk_menu_set_accel_group(GTK_MENU(menu->submenu_id), gui.accel_group); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu->id), menu->submenu_id); + # if !GTK_CHECK_VERSION(3,4,0) menu->tearoff_handle = gtk_tearoff_menu_item_new(); if (vim_strchr(p_go, GO_TEAROFF) != NULL) gtk_widget_show(menu->tearoff_handle); + # if GTK_CHECK_VERSION(3,0,0) + gtk_menu_shell_prepend(GTK_MENU_SHELL(menu->submenu_id), + menu->tearoff_handle); + # else gtk_menu_prepend(GTK_MENU(menu->submenu_id), menu->tearoff_handle); + # endif + # endif } static void *************** *** 494,500 **** --- 699,715 ---- if (menu_is_separator(menu->name)) { + # if GTK_CHECK_VERSION(3,0,0) + GtkToolItem *item = gtk_separator_tool_item_new(); + gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(item), + TRUE); + gtk_tool_item_set_expand(GTK_TOOL_ITEM(item), FALSE); + gtk_widget_show(GTK_WIDGET(item)); + + gtk_toolbar_insert(toolbar, item, idx); + # else gtk_toolbar_insert_space(toolbar, idx); + # endif menu->id = NULL; } else *************** *** 509,514 **** --- 724,747 ---- * a nasty GTK error message, skip the tooltip. */ CONVERT_TO_UTF8_FREE(tooltip); + # if GTK_CHECK_VERSION(3,0,0) + { + GtkWidget *icon; + GtkToolItem *item; + + icon = create_menu_icon(menu, + gtk_toolbar_get_icon_size(toolbar)); + item = gtk_tool_button_new(icon, (const gchar *)text); + gtk_tool_item_set_tooltip_text(item, (const gchar *)tooltip); + g_signal_connect(G_OBJECT(item), "clicked", + G_CALLBACK(&menu_item_activate), menu); + gtk_widget_show_all(GTK_WIDGET(item)); + + gtk_toolbar_insert(toolbar, item, idx); + + menu->id = GTK_WIDGET(item); + } + # else menu->id = gtk_toolbar_insert_item( toolbar, (const char *)text, *************** *** 518,527 **** --- 751,766 ---- G_CALLBACK(&menu_item_activate), menu, idx); + # endif if (gtk_socket_id != 0) + # if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(menu->id), "focus-in-event", + G_CALLBACK(toolbar_button_focus_in_event), NULL); + # else gtk_signal_connect(GTK_OBJECT(menu->id), "focus_in_event", GTK_SIGNAL_FUNC(toolbar_button_focus_in_event), NULL); + # endif CONVERT_TO_UTF8_FREE(text); CONVERT_TO_UTF8_FREE(tooltip); *************** *** 545,551 **** --- 784,795 ---- menu->id = gtk_menu_item_new(); gtk_widget_set_sensitive(menu->id, FALSE); gtk_widget_show(menu->id); + # if GTK_CHECK_VERSION(3,0,0) + gtk_menu_shell_insert(GTK_MENU_SHELL(parent->submenu_id), + menu->id, idx); + # else gtk_menu_insert(GTK_MENU(parent->submenu_id), menu->id, idx); + # endif return; } *************** *** 553,563 **** --- 797,817 ---- /* Add textual menu item. */ menu_item_new(menu, parent->submenu_id); gtk_widget_show(menu->id); + # if GTK_CHECK_VERSION(3,0,0) + gtk_menu_shell_insert(GTK_MENU_SHELL(parent->submenu_id), + menu->id, idx); + # else gtk_menu_insert(GTK_MENU(parent->submenu_id), menu->id, idx); + # endif if (menu->id != NULL) + # if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(menu->id), "activate", + G_CALLBACK(menu_item_activate), menu); + # else gtk_signal_connect(GTK_OBJECT(menu->id), "activate", GTK_SIGNAL_FUNC(menu_item_activate), menu); + # endif } } #endif /* FEAT_MENU */ *************** *** 592,597 **** --- 846,852 ---- } } + # if !GTK_CHECK_VERSION(3,4,0) static void recurse_tearoffs(vimmenu_T *menu, int val) { *************** *** 608,619 **** --- 863,883 ---- recurse_tearoffs(menu->children, val); } } + # endif + # if GTK_CHECK_VERSION(3,4,0) + void + gui_mch_toggle_tearoffs(int enable UNUSED) + { + /* Do nothing */ + } + # else void gui_mch_toggle_tearoffs(int enable) { recurse_tearoffs(root_menu, enable); } + # endif #endif /* FEAT_MENU */ #if defined(FEAT_TOOLBAR) *************** *** 644,653 **** char_u *tooltip; tooltip = CONVERT_TO_UTF8(menu->strings[MENU_INDEX_TIP]); ! if (tooltip == NULL || utf_valid_string(tooltip, NULL)) /* Only set the tooltip when it's valid utf-8. */ ! gtk_tooltips_set_tip(GTK_TOOLBAR(gui.toolbar)->tooltips, ! menu->id, (const char *)tooltip, NULL); CONVERT_TO_UTF8_FREE(tooltip); } } --- 908,922 ---- char_u *tooltip; tooltip = CONVERT_TO_UTF8(menu->strings[MENU_INDEX_TIP]); ! if (tooltip != NULL && utf_valid_string(tooltip, NULL)) ! # if GTK_CHECK_VERSION(3,0,0) /* Only set the tooltip when it's valid utf-8. */ ! gtk_widget_set_tooltip_text(menu->id, (const gchar *)tooltip); ! # else ! /* Only set the tooltip when it's valid utf-8. */ ! gtk_tooltips_set_tip(GTK_TOOLBAR(gui.toolbar)->tooltips, ! menu->id, (const char *)tooltip, NULL); ! # endif CONVERT_TO_UTF8_FREE(tooltip); } } *************** *** 676,683 **** --- 945,964 ---- if (menu->parent != NULL && menu_is_toolbar(menu->parent->name)) { if (menu_is_separator(menu->name)) + # if GTK_CHECK_VERSION(3,0,0) + { + GtkToolItem *item = NULL; + + item = gtk_toolbar_get_nth_item(GTK_TOOLBAR(gui.toolbar), + get_menu_position(menu)); + if (item != NULL) + gtk_container_remove(GTK_CONTAINER(gui.toolbar), + GTK_WIDGET(item)); + } + # else gtk_toolbar_remove_space(GTK_TOOLBAR(gui.toolbar), get_menu_position(menu)); + # endif else if (menu->id != NULL) gtk_widget_destroy(menu->id); } *************** *** 711,728 **** --- 992,1033 ---- adjustment = gtk_range_get_adjustment(GTK_RANGE(sb->id)); + #if GTK_CHECK_VERSION(3,0,0) + gtk_adjustment_set_lower(adjustment, 0.0); + gtk_adjustment_set_value(adjustment, val); + gtk_adjustment_set_upper(adjustment, max + 1); + gtk_adjustment_set_page_size(adjustment, size); + gtk_adjustment_set_page_increment(adjustment, + size < 3L ? 1L : size - 2L); + gtk_adjustment_set_step_increment(adjustment, 1.0); + #else adjustment->lower = 0.0; adjustment->value = val; adjustment->upper = max + 1; adjustment->page_size = size; adjustment->page_increment = size < 3L ? 1L : size - 2L; adjustment->step_increment = 1.0; + #endif + #if GTK_CHECK_VERSION(3,0,0) + g_signal_handler_block(G_OBJECT(adjustment), + (gulong)sb->handler_id); + #else g_signal_handler_block(GTK_OBJECT(adjustment), (gulong)sb->handler_id); + #endif + + #if !GTK_CHECK_VERSION(3,18,0) gtk_adjustment_changed(adjustment); + #endif + + #if GTK_CHECK_VERSION(3,0,0) + g_signal_handler_unblock(G_OBJECT(adjustment), + (gulong)sb->handler_id); + #else g_signal_handler_unblock(GTK_OBJECT(adjustment), (gulong)sb->handler_id); + #endif } } *************** *** 750,756 **** --- 1055,1066 ---- #endif sb = gui_find_scrollbar((long)data); + #if GTK_CHECK_VERSION(3,0,0) + value = gtk_adjustment_get_value(adjustment); + #else value = (long)adjustment->value; + #endif + #if !GTK_CHECK_VERSION(3,0,0) /* * The dragging argument must be right for the scrollbar to work with * closed folds. This isn't documented, hopefully this will keep on *************** *** 793,799 **** } } } ! gui_drag_scrollbar(sb, value, dragging); } --- 1103,1109 ---- } } } ! #endif /* !GTK_CHECK_VERSION(3,0,0) */ gui_drag_scrollbar(sb, value, dragging); } *************** *** 802,824 **** --- 1112,1153 ---- gui_mch_create_scrollbar(scrollbar_T *sb, int orient) { if (orient == SBAR_HORIZ) + #if GTK_CHECK_VERSION(3,2,0) + sb->id = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, NULL); + #else sb->id = gtk_hscrollbar_new(NULL); + #endif else if (orient == SBAR_VERT) + #if GTK_CHECK_VERSION(3,2,0) + sb->id = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, NULL); + #else sb->id = gtk_vscrollbar_new(NULL); + #endif if (sb->id != NULL) { GtkAdjustment *adjustment; + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_can_focus(sb->id, FALSE); + #else GTK_WIDGET_UNSET_FLAGS(sb->id, GTK_CAN_FOCUS); + #endif gtk_form_put(GTK_FORM(gui.formwin), sb->id, 0, 0); adjustment = gtk_range_get_adjustment(GTK_RANGE(sb->id)); + #if GTK_CHECK_VERSION(3,0,0) + sb->handler_id = g_signal_connect( + G_OBJECT(adjustment), "value-changed", + G_CALLBACK(adjustment_value_changed), + GINT_TO_POINTER(sb->ident)); + #else sb->handler_id = gtk_signal_connect( GTK_OBJECT(adjustment), "value_changed", GTK_SIGNAL_FUNC(adjustment_value_changed), GINT_TO_POINTER(sb->ident)); + #endif gui_mch_update(); } } *************** *** 932,939 **** --- 1261,1273 ---- GTK_WINDOW(gui.mainwin), saving ? GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN, + # if GTK_CHECK_VERSION(3,10,0) + _("_Cancel"), GTK_RESPONSE_CANCEL, + saving ? _("_Save") : _("_Open"), GTK_RESPONSE_ACCEPT, + # else GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, saving ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + # endif NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fc), (const gchar *)dirbuf); *************** *** 991,997 **** } gtk_widget_destroy(GTK_WIDGET(fc)); ! #else if (gui.filedlg == NULL) { --- 1325,1331 ---- } gtk_widget_destroy(GTK_WIDGET(fc)); ! #else /* !USE_FILE_CHOOSER */ if (gui.filedlg == NULL) { *************** *** 1027,1033 **** gtk_widget_show(gui.filedlg); gtk_main(); ! #endif g_log_remove_handler(domain, log_handler); CONVERT_TO_UTF8_FREE(title); --- 1361,1367 ---- gtk_widget_show(gui.filedlg); gtk_main(); ! #endif /* !USE_FILE_CHOOSER */ g_log_remove_handler(domain, log_handler); CONVERT_TO_UTF8_FREE(title); *************** *** 1062,1069 **** --- 1396,1408 ---- (const gchar *)title, GTK_WINDOW(gui.mainwin), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, + # if GTK_CHECK_VERSION(3,10,0) + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_OK"), GTK_RESPONSE_ACCEPT, + # else GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + # endif NULL); CONVERT_TO_UTF8_FREE(title); *************** *** 1096,1105 **** g_free(dirname); return p; ! # else /* For GTK 2.2 and earlier: fall back to ordinary file selector. */ return gui_mch_browse(0, title, NULL, NULL, initdir, NULL); ! # endif } --- 1435,1444 ---- g_free(dirname); return p; ! # else /* !defined(GTK_FILE_CHOOSER) */ /* For GTK 2.2 and earlier: fall back to ordinary file selector. */ return gui_mch_browse(0, title, NULL, NULL, initdir, NULL); ! # endif /* !defined(GTK_FILE_CHOOSER) */ } *************** *** 1266,1271 **** --- 1605,1615 ---- /* Check 'v' flag in 'guioptions': vertical button placement. */ if (vim_strchr(p_go, GO_VERTICAL) != NULL) { + # if GTK_CHECK_VERSION(3,0,0) + /* Add GTK+ 3 code if necessary. */ + /* N.B. GTK+ 3 doesn't allow you to access vbox and action_area via + * the C API. */ + # else GtkWidget *vbutton_box; vbutton_box = gtk_vbutton_box_new(); *************** *** 1274,1279 **** --- 1618,1624 ---- vbutton_box, TRUE, FALSE, 0); /* Overrule the "action_area" value, hopefully this works... */ GTK_DIALOG(dialog)->action_area = vbutton_box; + # endif } /* *************** *** 1308,1313 **** --- 1653,1668 ---- */ if (ok != NULL && ync != NULL) /* almost impossible to fail */ { + # if GTK_CHECK_VERSION(3,10,0) + if (button_equal(label, ok[0])) label = _("OK"); + else if (button_equal(label, ync[0])) label = _("Yes"); + else if (button_equal(label, ync[1])) label = _("No"); + else if (button_equal(label, ync[2])) label = _("Cancel"); + else if (button_equal(label, "Ok")) label = _("OK"); + else if (button_equal(label, "Yes")) label = _("Yes"); + else if (button_equal(label, "No")) label = _("No"); + else if (button_equal(label, "Cancel")) label = _("Canccl"); + # else if (button_equal(label, ok[0])) label = GTK_STOCK_OK; else if (button_equal(label, ync[0])) label = GTK_STOCK_YES; else if (button_equal(label, ync[1])) label = GTK_STOCK_NO; *************** *** 1316,1321 **** --- 1671,1677 ---- else if (button_equal(label, "Yes")) label = GTK_STOCK_YES; else if (button_equal(label, "No")) label = GTK_STOCK_NO; else if (button_equal(label, "Cancel")) label = GTK_STOCK_CANCEL; + # endif } label8 = CONVERT_TO_UTF8((char_u *)label); gtk_dialog_add_button(dialog, (const gchar *)label8, idx); *************** *** 1408,1421 **** --- 1764,1795 ---- gtk_entry_set_text(GTK_ENTRY(entry), (const char *)text); CONVERT_TO_UTF8_FREE(text); + # if GTK_CHECK_VERSION(3,14,0) + gtk_widget_set_halign(GTK_WIDGET(entry), GTK_ALIGN_CENTER); + gtk_widget_set_valign(GTK_WIDGET(entry), GTK_ALIGN_CENTER); + gtk_widget_set_hexpand(GTK_WIDGET(entry), TRUE); + gtk_widget_set_vexpand(GTK_WIDGET(entry), TRUE); + + alignment = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + # else alignment = gtk_alignment_new((float)0.5, (float)0.5, (float)1.0, (float)1.0); + # endif gtk_container_add(GTK_CONTAINER(alignment), entry); gtk_container_set_border_width(GTK_CONTAINER(alignment), 5); gtk_widget_show(alignment); + # if GTK_CHECK_VERSION(3,0,0) + { + GtkWidget * const vbox + = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + gtk_box_pack_start(GTK_BOX(vbox), + alignment, TRUE, FALSE, 0); + } + # else gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), alignment, TRUE, FALSE, 0); + # endif dialoginfo.noalt = FALSE; } else *************** *** 1473,1478 **** --- 1847,1853 ---- * Append a submenu for selecting an input method. This is * currently the only way to switch input methods at runtime. */ + # if !GTK_CHECK_VERSION(3,10,0) if (xic != NULL && g_object_get_data(G_OBJECT(menu->submenu_id), "vim-has-im-menu") == NULL) { *************** *** 1499,1504 **** --- 1874,1880 ---- g_object_set_data(G_OBJECT(menu->submenu_id), "vim-has-im-menu", GINT_TO_POINTER(TRUE)); } + # endif # endif /* FEAT_XIM */ gtk_menu_popup(GTK_MENU(menu->submenu_id), *************** *** 1524,1530 **** --- 1900,1910 ---- gboolean *push_in UNUSED, gpointer user_data UNUSED) { + # if GTK_CHECK_VERSION(3,0,0) + gdk_window_get_origin(gtk_widget_get_window(gui.drawarea), x, y); + # else gdk_window_get_origin(gui.drawarea->window, x, y); + # endif if (popup_mouse_pos) { *************** *** 1534,1540 **** --- 1914,1925 ---- *x += mx; *y += my; } + # if GTK_CHECK_VERSION(3,0,0) + else if (curwin != NULL && gui.drawarea != NULL && + gtk_widget_get_window(gui.drawarea) != NULL) + # else else if (curwin != NULL && gui.drawarea != NULL && gui.drawarea->window != NULL) + # endif { /* Find the cursor position in the current window */ *x += FILL_X(W_WINCOL(curwin) + curwin->w_wcol + 1) + 1; *************** *** 1612,1618 **** } static GtkWidget * ! create_image_button(const char *stock_id, const char *label) { char_u *text; GtkWidget *box; --- 1997,2009 ---- } static GtkWidget * ! #if GTK_CHECK_VERSION(3,10,0) ! create_image_button(const char *stock_id UNUSED, ! const char *label) ! #else ! create_image_button(const char *stock_id, ! const char *label) ! #endif { char_u *text; GtkWidget *box; *************** *** 1621,1638 **** text = CONVERT_TO_UTF8((char_u *)label); box = gtk_hbox_new(FALSE, 3); ! gtk_box_pack_start(GTK_BOX(box), ! gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_BUTTON), ! FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(box), gtk_label_new((const char *)text), FALSE, FALSE, 0); CONVERT_TO_UTF8_FREE(text); alignment = gtk_alignment_new((float)0.5, (float)0.5, (float)0.0, (float)0.0); gtk_container_add(GTK_CONTAINER(alignment), box); gtk_widget_show_all(alignment); --- 2012,2046 ---- text = CONVERT_TO_UTF8((char_u *)label); + #if GTK_CHECK_VERSION(3,2,0) + box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 3); + gtk_box_set_homogeneous(GTK_BOX(box), FALSE); + #else box = gtk_hbox_new(FALSE, 3); ! #endif ! #if !GTK_CHECK_VERSION(3,10,0) ! if (stock_id != NULL) ! gtk_box_pack_start(GTK_BOX(box), ! gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_BUTTON), ! FALSE, FALSE, 0); ! #endif gtk_box_pack_start(GTK_BOX(box), gtk_label_new((const char *)text), FALSE, FALSE, 0); CONVERT_TO_UTF8_FREE(text); + #if GTK_CHECK_VERSION(3,14,0) + gtk_widget_set_halign(GTK_WIDGET(box), GTK_ALIGN_CENTER); + gtk_widget_set_valign(GTK_WIDGET(box), GTK_ALIGN_CENTER); + gtk_widget_set_hexpand(GTK_WIDGET(box), TRUE); + gtk_widget_set_vexpand(GTK_WIDGET(box), TRUE); + + alignment = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + #else alignment = gtk_alignment_new((float)0.5, (float)0.5, (float)0.0, (float)0.0); + #endif gtk_container_add(GTK_CONTAINER(alignment), box); gtk_widget_show_all(alignment); *************** *** 1695,1704 **** --- 2103,2119 ---- if (entry_text != NULL) { gtk_entry_set_text(GTK_ENTRY(frdp->what), (char *)entry_text); + #if GTK_CHECK_VERSION(3,0,0) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frdp->wword), + (gboolean)wword); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frdp->mcase), + (gboolean)mcase); + #else gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(frdp->wword), (gboolean)wword); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(frdp->mcase), (gboolean)mcase); + #endif } gtk_window_present(GTK_WINDOW(frdp->dialog)); vim_free(entry_text); *************** *** 1706,1712 **** --- 2121,2131 ---- } frdp->dialog = gtk_dialog_new(); + #if GTK_CHECK_VERSION(3,0,0) + /* Nothing equivalent to gtk_dialog_set_has_separator() in GTK+ 3. */ + #else gtk_dialog_set_has_separator(GTK_DIALOG(frdp->dialog), FALSE); + #endif gtk_window_set_transient_for(GTK_WINDOW(frdp->dialog), GTK_WINDOW(gui.mainwin)); gtk_window_set_destroy_with_parent(GTK_WINDOW(frdp->dialog), TRUE); *************** *** 1721,1884 **** --- 2140,2541 ---- CONV(_("VIM - Search..."))); } + #if GTK_CHECK_VERSION(3,2,0) + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_set_homogeneous(GTK_BOX(hbox), FALSE); + #else hbox = gtk_hbox_new(FALSE, 0); + #endif gtk_container_set_border_width(GTK_CONTAINER(hbox), 10); + #if GTK_CHECK_VERSION(3,0,0) + { + GtkWidget * const dialog_vbox + = gtk_dialog_get_content_area(GTK_DIALOG(frdp->dialog)); + gtk_container_add(GTK_CONTAINER(dialog_vbox), hbox); + } + #else gtk_container_add(GTK_CONTAINER(GTK_DIALOG(frdp->dialog)->vbox), hbox); + #endif if (do_replace) + #if GTK_CHECK_VERSION(3,4,0) + table = gtk_grid_new(); + #else table = gtk_table_new(1024, 4, FALSE); + #endif else + #if GTK_CHECK_VERSION(3,4,0) + table = gtk_grid_new(); + #else table = gtk_table_new(1024, 3, FALSE); + #endif gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 0); + #if GTK_CHECK_VERSION(3,0,0) + gtk_container_set_border_width(GTK_CONTAINER(table), 4); + #else gtk_container_border_width(GTK_CONTAINER(table), 4); + #endif tmp = gtk_label_new(CONV(_("Find what:"))); + #if GTK_CHECK_VERSION(3,16,0) + gtk_label_set_xalign(GTK_LABEL(tmp), 0.0); + gtk_label_set_yalign(GTK_LABEL(tmp), 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.0); + g_object_set_property(G_OBJECT(tmp), "xalign", &align_val); + + g_value_set_float(&align_val, 0.5); + g_object_set_property(G_OBJECT(tmp), "yalign", &align_val); + + g_value_unset(&align_val); + } + #else gtk_misc_set_alignment(GTK_MISC(tmp), (gfloat)0.0, (gfloat)0.5); + #endif + #if GTK_CHECK_VERSION(3,4,0) + gtk_grid_attach(GTK_GRID(table), tmp, 0, 0, 2, 1); + #else gtk_table_attach(GTK_TABLE(table), tmp, 0, 1, 0, 1, GTK_FILL, GTK_EXPAND, 2, 2); + #endif frdp->what = gtk_entry_new(); sensitive = (entry_text != NULL && entry_text[0] != NUL); if (entry_text != NULL) gtk_entry_set_text(GTK_ENTRY(frdp->what), (char *)entry_text); + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(frdp->what), "changed", + G_CALLBACK(entry_changed_cb), frdp->dialog); + g_signal_connect_after(G_OBJECT(frdp->what), "key-press-event", + G_CALLBACK(find_key_press_event), + (gpointer) frdp); + #else gtk_signal_connect(GTK_OBJECT(frdp->what), "changed", GTK_SIGNAL_FUNC(entry_changed_cb), frdp->dialog); gtk_signal_connect_after(GTK_OBJECT(frdp->what), "key_press_event", GTK_SIGNAL_FUNC(find_key_press_event), (gpointer) frdp); + #endif + #if GTK_CHECK_VERSION(3,4,0) + gtk_grid_attach(GTK_GRID(table), frdp->what, 2, 0, 5, 1); + #else gtk_table_attach(GTK_TABLE(table), frdp->what, 1, 1024, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND, 2, 2); + #endif if (do_replace) { tmp = gtk_label_new(CONV(_("Replace with:"))); + #if GTK_CHECK_VERSION(3,16,0) + gtk_label_set_xalign(GTK_LABEL(tmp), 0.0); + gtk_label_set_yalign(GTK_LABEL(tmp), 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.0); + g_object_set_property(G_OBJECT(tmp), "xalign", &align_val); + + g_value_set_float(&align_val, 0.5); + g_object_set_property(G_OBJECT(tmp), "yalign", &align_val); + + g_value_unset(&align_val); + } + #else gtk_misc_set_alignment(GTK_MISC(tmp), (gfloat)0.0, (gfloat)0.5); + #endif + #if GTK_CHECK_VERSION(3,4,0) + gtk_grid_attach(GTK_GRID(table), tmp, 0, 1, 2, 1); + #else gtk_table_attach(GTK_TABLE(table), tmp, 0, 1, 1, 2, GTK_FILL, GTK_EXPAND, 2, 2); + #endif frdp->with = gtk_entry_new(); + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(frdp->with), "activate", + G_CALLBACK(find_replace_cb), + GINT_TO_POINTER(FRD_R_FINDNEXT)); + g_signal_connect_after(G_OBJECT(frdp->with), "key-press-event", + G_CALLBACK(find_key_press_event), + (gpointer) frdp); + #else gtk_signal_connect(GTK_OBJECT(frdp->with), "activate", GTK_SIGNAL_FUNC(find_replace_cb), GINT_TO_POINTER(FRD_R_FINDNEXT)); gtk_signal_connect_after(GTK_OBJECT(frdp->with), "key_press_event", GTK_SIGNAL_FUNC(find_key_press_event), (gpointer) frdp); + #endif + #if GTK_CHECK_VERSION(3,4,0) + gtk_grid_attach(GTK_GRID(table), frdp->with, 2, 1, 5, 1); + #else gtk_table_attach(GTK_TABLE(table), frdp->with, 1, 1024, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND, 2, 2); + #endif /* * Make the entry activation only change the input focus onto the * with item. */ + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(frdp->what), "activate", + G_CALLBACK(entry_activate_cb), frdp->with); + #else gtk_signal_connect(GTK_OBJECT(frdp->what), "activate", GTK_SIGNAL_FUNC(entry_activate_cb), frdp->with); + #endif } else { /* * Make the entry activation do the search. */ + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(frdp->what), "activate", + G_CALLBACK(find_replace_cb), + GINT_TO_POINTER(FRD_FINDNEXT)); + #else gtk_signal_connect(GTK_OBJECT(frdp->what), "activate", GTK_SIGNAL_FUNC(find_replace_cb), GINT_TO_POINTER(FRD_FINDNEXT)); + #endif } /* whole word only button */ frdp->wword = gtk_check_button_new_with_label(CONV(_("Match whole word only"))); + #if GTK_CHECK_VERSION(3,0,0) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frdp->wword), + (gboolean)wword); + #else gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(frdp->wword), (gboolean)wword); + #endif if (do_replace) + #if GTK_CHECK_VERSION(3,4,0) + gtk_grid_attach(GTK_GRID(table), frdp->wword, 0, 2, 5, 1); + #else gtk_table_attach(GTK_TABLE(table), frdp->wword, 0, 1023, 2, 3, GTK_FILL, GTK_EXPAND, 2, 2); + #endif else + #if GTK_CHECK_VERSION(3,4,0) + gtk_grid_attach(GTK_GRID(table), frdp->wword, 0, 3, 5, 1); + #else gtk_table_attach(GTK_TABLE(table), frdp->wword, 0, 1023, 1, 2, GTK_FILL, GTK_EXPAND, 2, 2); + #endif /* match case button */ frdp->mcase = gtk_check_button_new_with_label(CONV(_("Match case"))); + #if GTK_CHECK_VERSION(3,0,0) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frdp->mcase), + (gboolean)mcase); + #else gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(frdp->mcase), (gboolean)mcase); + #endif if (do_replace) + #if GTK_CHECK_VERSION(3,4,0) + gtk_grid_attach(GTK_GRID(table), frdp->mcase, 0, 3, 5, 1); + #else gtk_table_attach(GTK_TABLE(table), frdp->mcase, 0, 1023, 3, 4, GTK_FILL, GTK_EXPAND, 2, 2); + #endif else + #if GTK_CHECK_VERSION(3,4,0) + gtk_grid_attach(GTK_GRID(table), frdp->mcase, 0, 4, 5, 1); + #else gtk_table_attach(GTK_TABLE(table), frdp->mcase, 0, 1023, 2, 3, GTK_FILL, GTK_EXPAND, 2, 2); + #endif tmp = gtk_frame_new(CONV(_("Direction"))); if (do_replace) + #if GTK_CHECK_VERSION(3,4,0) + gtk_grid_attach(GTK_GRID(table), tmp, 5, 2, 2, 4); + #else gtk_table_attach(GTK_TABLE(table), tmp, 1023, 1024, 2, 4, GTK_FILL, GTK_FILL, 2, 2); + #endif else + #if GTK_CHECK_VERSION(3,4,0) + gtk_grid_attach(GTK_GRID(table), tmp, 5, 2, 1, 3); + #else gtk_table_attach(GTK_TABLE(table), tmp, 1023, 1024, 1, 3, GTK_FILL, GTK_FILL, 2, 2); + #endif + #if GTK_CHECK_VERSION(3,2,0) + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE); + #else vbox = gtk_vbox_new(FALSE, 0); + #endif + #if GTK_CHECK_VERSION(3,0,0) + gtk_container_set_border_width(GTK_CONTAINER(vbox), 0); + #else gtk_container_border_width(GTK_CONTAINER(vbox), 0); + #endif gtk_container_add(GTK_CONTAINER(tmp), vbox); /* 'Up' and 'Down' buttons */ frdp->up = gtk_radio_button_new_with_label(NULL, CONV(_("Up"))); gtk_box_pack_start(GTK_BOX(vbox), frdp->up, TRUE, TRUE, 0); + #if GTK_CHECK_VERSION(3,0,0) + frdp->down = gtk_radio_button_new_with_label( + gtk_radio_button_get_group(GTK_RADIO_BUTTON(frdp->up)), + CONV(_("Down"))); + #else frdp->down = gtk_radio_button_new_with_label( gtk_radio_button_group(GTK_RADIO_BUTTON(frdp->up)), CONV(_("Down"))); + #endif + #if GTK_CHECK_VERSION(3,0,0) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frdp->down), TRUE); + #else gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(frdp->down), TRUE); + #endif gtk_container_set_border_width(GTK_CONTAINER(vbox), 2); gtk_box_pack_start(GTK_BOX(vbox), frdp->down, TRUE, TRUE, 0); /* vbox to hold the action buttons */ + #if GTK_CHECK_VERSION(3,2,0) + actionarea = gtk_button_box_new(GTK_ORIENTATION_VERTICAL); + #else actionarea = gtk_vbutton_box_new(); + #endif + #if GTK_CHECK_VERSION(3,0,0) + gtk_container_set_border_width(GTK_CONTAINER(actionarea), 2); + #else gtk_container_border_width(GTK_CONTAINER(actionarea), 2); + #endif gtk_box_pack_end(GTK_BOX(hbox), actionarea, FALSE, FALSE, 0); /* 'Find Next' button */ + #if GTK_CHECK_VERSION(3,10,0) + frdp->find = create_image_button(NULL, _("Find Next")); + #else frdp->find = create_image_button(GTK_STOCK_FIND, _("Find Next")); + #endif gtk_widget_set_sensitive(frdp->find, sensitive); + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(frdp->find), "clicked", + G_CALLBACK(find_replace_cb), + (do_replace) ? GINT_TO_POINTER(FRD_R_FINDNEXT) + : GINT_TO_POINTER(FRD_FINDNEXT)); + #else gtk_signal_connect(GTK_OBJECT(frdp->find), "clicked", GTK_SIGNAL_FUNC(find_replace_cb), (do_replace) ? GINT_TO_POINTER(FRD_R_FINDNEXT) : GINT_TO_POINTER(FRD_FINDNEXT)); + #endif + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_can_default(frdp->find, TRUE); + #else GTK_WIDGET_SET_FLAGS(frdp->find, GTK_CAN_DEFAULT); + #endif gtk_box_pack_start(GTK_BOX(actionarea), frdp->find, FALSE, FALSE, 0); gtk_widget_grab_default(frdp->find); if (do_replace) { /* 'Replace' button */ + #if GTK_CHECK_VERSION(3,10,0) + frdp->replace = create_image_button(NULL, _("Replace")); + #else frdp->replace = create_image_button(GTK_STOCK_CONVERT, _("Replace")); + #endif gtk_widget_set_sensitive(frdp->replace, sensitive); + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_can_default(frdp->find, TRUE); + #else GTK_WIDGET_SET_FLAGS(frdp->replace, GTK_CAN_DEFAULT); + #endif gtk_box_pack_start(GTK_BOX(actionarea), frdp->replace, FALSE, FALSE, 0); + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(frdp->replace), "clicked", + G_CALLBACK(find_replace_cb), + GINT_TO_POINTER(FRD_REPLACE)); + #else gtk_signal_connect(GTK_OBJECT(frdp->replace), "clicked", GTK_SIGNAL_FUNC(find_replace_cb), GINT_TO_POINTER(FRD_REPLACE)); + #endif /* 'Replace All' button */ + #if GTK_CHECK_VERSION(3,10,0) + frdp->all = create_image_button(NULL, _("Replace All")); + #else frdp->all = create_image_button(GTK_STOCK_CONVERT, _("Replace All")); + #endif gtk_widget_set_sensitive(frdp->all, sensitive); + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_can_default(frdp->all, TRUE); + #else GTK_WIDGET_SET_FLAGS(frdp->all, GTK_CAN_DEFAULT); + #endif gtk_box_pack_start(GTK_BOX(actionarea), frdp->all, FALSE, FALSE, 0); + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(frdp->all), "clicked", + G_CALLBACK(find_replace_cb), + GINT_TO_POINTER(FRD_REPLACEALL)); + #else gtk_signal_connect(GTK_OBJECT(frdp->all), "clicked", GTK_SIGNAL_FUNC(find_replace_cb), GINT_TO_POINTER(FRD_REPLACEALL)); + #endif } /* 'Cancel' button */ + #if GTK_CHECK_VERSION(3,10,0) + tmp = gtk_button_new_with_mnemonic(_("_Close")); + #else tmp = gtk_button_new_from_stock(GTK_STOCK_CLOSE); + #endif + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_can_default(tmp, TRUE); + #else GTK_WIDGET_SET_FLAGS(tmp, GTK_CAN_DEFAULT); + #endif gtk_box_pack_end(GTK_BOX(actionarea), tmp, FALSE, FALSE, 0); + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect_swapped(G_OBJECT(tmp), + "clicked", G_CALLBACK(gtk_widget_hide), + G_OBJECT(frdp->dialog)); + g_signal_connect_swapped(G_OBJECT(frdp->dialog), + "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), + G_OBJECT(frdp->dialog)); + #else gtk_signal_connect_object(GTK_OBJECT(tmp), "clicked", GTK_SIGNAL_FUNC(gtk_widget_hide), GTK_OBJECT(frdp->dialog)); gtk_signal_connect_object(GTK_OBJECT(frdp->dialog), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_hide_on_delete), GTK_OBJECT(frdp->dialog)); + #endif + #if GTK_CHECK_VERSION(3,2,0) + tmp = gtk_separator_new(GTK_ORIENTATION_VERTICAL); + #else tmp = gtk_vseparator_new(); + #endif gtk_box_pack_end(GTK_BOX(hbox), tmp, FALSE, FALSE, 10); /* Suppress automatic show of the unused action area */ + #if GTK_CHECK_VERSION(3,0,0) + # if !GTK_CHECK_VERSION(3,12,0) + gtk_widget_hide(gtk_dialog_get_action_area(GTK_DIALOG(frdp->dialog))); + # endif + #else gtk_widget_hide(GTK_DIALOG(frdp->dialog)->action_area); + #endif gtk_widget_show_all(hbox); gtk_widget_show(frdp->dialog); *************** *** 1928,1938 **** --- 2585,2607 ---- } find_text = (char_u *)gtk_entry_get_text(GTK_ENTRY(sfr->what)); + #if GTK_CHECK_VERSION(3,0,0) + direction_down = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sfr->down)); + #else direction_down = GTK_TOGGLE_BUTTON(sfr->down)->active; + #endif + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sfr->wword))) + #else if (GTK_TOGGLE_BUTTON(sfr->wword)->active) + #endif flags |= FRD_WHOLE_WORD; + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sfr->mcase))) + #else if (GTK_TOGGLE_BUTTON(sfr->mcase)->active) + #endif flags |= FRD_MATCH_CASE; repl_text = CONVERT_FROM_UTF8(repl_text); *** ../vim-7.4.1401/src/gui_gtk_f.c 2010-06-25 04:51:05.000000000 +0200 --- src/gui_gtk_f.c 2016-02-23 16:36:54.440234538 +0100 *************** *** 19,31 **** * children at arbitrary positions width arbitrary sizes. This finally puts * an end on our resize problems with which we where struggling for such a * long time. */ #include "vim.h" #include /* without this it compiles, but gives errors at runtime! */ #include "gui_gtk_f.h" ! #include #ifdef WIN3264 # include #else --- 19,37 ---- * children at arbitrary positions width arbitrary sizes. This finally puts * an end on our resize problems with which we where struggling for such a * long time. + * + * Support for GTK+ 3 was added by: + * + * 2016 Kazunobu Kuriyama */ #include "vim.h" #include /* without this it compiles, but gives errors at runtime! */ #include "gui_gtk_f.h" ! #if !GTK_CHECK_VERSION(3,0,0) ! # include ! #endif #ifdef WIN3264 # include #else *************** *** 52,61 **** --- 58,80 ---- static void gtk_form_map(GtkWidget *widget); static void gtk_form_size_request(GtkWidget *widget, GtkRequisition *requisition); + #if GTK_CHECK_VERSION(3,0,0) + static void gtk_form_get_preferred_width(GtkWidget *widget, + gint *minimal_width, + gint *natural_width); + static void gtk_form_get_preferred_height(GtkWidget *widget, + gint *minimal_height, + gint *natural_height); + #endif static void gtk_form_size_allocate(GtkWidget *widget, GtkAllocation *allocation); + #if GTK_CHECK_VERSION(3,0,0) + static gboolean gtk_form_draw(GtkWidget *widget, + cairo_t *cr); + #else static gint gtk_form_expose(GtkWidget *widget, GdkEventExpose *event); + #endif static void gtk_form_remove(GtkContainer *container, GtkWidget *widget); *************** *** 73,94 **** gboolean force_allocate); static void gtk_form_position_children(GtkForm *form); static GdkFilterReturn gtk_form_filter(GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data); static GdkFilterReturn gtk_form_main_filter(GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data); ! static void gtk_form_set_static_gravity(GdkWindow *window, gboolean use_static); static void gtk_form_send_configure(GtkForm *form); static void gtk_form_child_map(GtkWidget *widget, gpointer user_data); static void gtk_form_child_unmap(GtkWidget *widget, gpointer user_data); static GtkWidgetClass *parent_class = NULL; /* Public interface */ --- 92,118 ---- gboolean force_allocate); static void gtk_form_position_children(GtkForm *form); + #if !GTK_CHECK_VERSION(3,0,0) static GdkFilterReturn gtk_form_filter(GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data); static GdkFilterReturn gtk_form_main_filter(GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data); ! #endif ! #if !GTK_CHECK_VERSION(3,16,0) static void gtk_form_set_static_gravity(GdkWindow *window, gboolean use_static); + #endif static void gtk_form_send_configure(GtkForm *form); static void gtk_form_child_map(GtkWidget *widget, gpointer user_data); static void gtk_form_child_unmap(GtkWidget *widget, gpointer user_data); + #if !GTK_CHECK_VERSION(3,0,0) static GtkWidgetClass *parent_class = NULL; + #endif /* Public interface */ *************** *** 98,104 **** --- 122,132 ---- { GtkForm *form; + #if GTK_CHECK_VERSION(3,0,0) + form = g_object_new(GTK_TYPE_FORM, NULL); + #else form = gtk_type_new(gtk_form_get_type()); + #endif return GTK_WIDGET(form); } *************** *** 120,127 **** --- 148,159 ---- child->window = NULL; child->x = x; child->y = y; + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_size_request(child->widget, -1, -1); + #else child->widget->requisition.width = 0; child->widget->requisition.height = 0; + #endif child->mapped = FALSE; form->children = g_list_append(form->children, child); *************** *** 131,143 **** --- 163,186 ---- * that gtk_widget_set_parent() realizes the widget if it's visible * and its parent is mapped. */ + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_realized(GTK_WIDGET(form))) + #else if (GTK_WIDGET_REALIZED(form)) + #endif gtk_form_attach_child_window(form, child); gtk_widget_set_parent(child_widget, GTK_WIDGET(form)); + #if !GTK_CHECK_VERSION(3,0,0) gtk_widget_size_request(child->widget, NULL); + #endif + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_realized(GTK_WIDGET(form)) + && !gtk_widget_get_realized(child_widget)) + #else if (GTK_WIDGET_REALIZED(form) && !GTK_WIDGET_REALIZED(child_widget)) + #endif gtk_form_realize_child(form, child); gtk_form_position_child(form, child, TRUE); *************** *** 193,198 **** --- 236,244 ---- /* Basic Object handling procedures */ + #if GTK_CHECK_VERSION(3,0,0) + G_DEFINE_TYPE(GtkForm, gtk_form, GTK_TYPE_CONTAINER) + #else GtkType gtk_form_get_type(void) { *************** *** 213,218 **** --- 259,265 ---- } return form_type; } + #endif /* !GTK_CHECK_VERSION(3,0,0) */ static void gtk_form_class_init(GtkFormClass *klass) *************** *** 223,236 **** --- 270,294 ---- widget_class = (GtkWidgetClass *) klass; container_class = (GtkContainerClass *) klass; + #if !GTK_CHECK_VERSION(3,0,0) parent_class = gtk_type_class(gtk_container_get_type()); + #endif widget_class->realize = gtk_form_realize; widget_class->unrealize = gtk_form_unrealize; widget_class->map = gtk_form_map; + #if GTK_CHECK_VERSION(3,0,0) + widget_class->get_preferred_width = gtk_form_get_preferred_width; + widget_class->get_preferred_height = gtk_form_get_preferred_height; + #else widget_class->size_request = gtk_form_size_request; + #endif widget_class->size_allocate = gtk_form_size_allocate; + #if GTK_CHECK_VERSION(3,0,0) + widget_class->draw = gtk_form_draw; + #else widget_class->expose_event = gtk_form_expose; + #endif container_class->remove = gtk_form_remove; container_class->forall = gtk_form_forall; *************** *** 239,253 **** --- 297,318 ---- static void gtk_form_init(GtkForm *form) { + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_has_window(GTK_WIDGET(form), TRUE); + #endif form->children = NULL; + #if !GTK_CHECK_VERSION(3,0,0) form->width = 1; form->height = 1; + #endif form->bin_window = NULL; + #if !GTK_CHECK_VERSION(3,0,0) form->configure_serial = 0; form->visibility = GDK_VISIBILITY_PARTIAL; + #endif form->freeze_count = 0; } *************** *** 267,306 **** --- 332,423 ---- g_return_if_fail(GTK_IS_FORM(widget)); form = GTK_FORM(widget); + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_realized(widget, TRUE); + #else GTK_WIDGET_SET_FLAGS(form, GTK_REALIZED); + #endif attributes.window_type = GDK_WINDOW_CHILD; + #if GTK_CHECK_VERSION(3,0,0) + { + GtkAllocation allocation; + gtk_widget_get_allocation(widget, &allocation); + attributes.x = allocation.x; + attributes.y = allocation.y; + attributes.width = allocation.width; + attributes.height = allocation.height; + } + #else attributes.x = widget->allocation.x; attributes.y = widget->allocation.y; attributes.width = widget->allocation.width; attributes.height = widget->allocation.height; + #endif attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual(widget); + #if GTK_CHECK_VERSION(3,0,0) + attributes.event_mask = GDK_EXPOSURE_MASK; + #else attributes.colormap = gtk_widget_get_colormap(widget); attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK; + #endif + #if GTK_CHECK_VERSION(3,0,0) + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; + #else attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + #endif + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_window(widget, + gdk_window_new(gtk_widget_get_parent_window(widget), + &attributes, attributes_mask)); + gdk_window_set_user_data(gtk_widget_get_window(widget), widget); + #else widget->window = gdk_window_new(gtk_widget_get_parent_window(widget), &attributes, attributes_mask); gdk_window_set_user_data(widget->window, widget); + #endif attributes.x = 0; attributes.y = 0; attributes.event_mask = gtk_widget_get_events(widget); + #if GTK_CHECK_VERSION(3,0,0) + form->bin_window = gdk_window_new(gtk_widget_get_window(widget), + &attributes, attributes_mask); + #else form->bin_window = gdk_window_new(widget->window, &attributes, attributes_mask); + #endif gdk_window_set_user_data(form->bin_window, widget); + #if !GTK_CHECK_VERSION(3,16,0) gtk_form_set_static_gravity(form->bin_window, TRUE); + #endif + + #if GTK_CHECK_VERSION(3,0,0) + { + GtkStyleContext * const sctx = gtk_widget_get_style_context(widget); + gtk_style_context_add_class(sctx, "gtk-form"); + gtk_style_context_set_state(sctx, GTK_STATE_FLAG_NORMAL); + # if !GTK_CHECK_VERSION(3,18,0) + gtk_style_context_set_background(sctx, gtk_widget_get_window(widget)); + gtk_style_context_set_background(sctx, form->bin_window); + # endif + } + #else widget->style = gtk_style_attach(widget->style, widget->window); gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL); gtk_style_set_background(widget->style, form->bin_window, GTK_STATE_NORMAL); + #endif + #if !GTK_CHECK_VERSION(3,0,0) gdk_window_add_filter(widget->window, gtk_form_main_filter, form); gdk_window_add_filter(form->bin_window, gtk_form_filter, form); + #endif for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next) { *************** *** 308,314 **** --- 425,435 ---- gtk_form_attach_child_window(form, child); + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_visible(child->widget)) + #else if (GTK_WIDGET_VISIBLE(child->widget)) + #endif gtk_form_realize_child(form, child); } } *************** *** 332,348 **** --- 453,482 ---- form = GTK_FORM(widget); + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_mapped(widget, TRUE); + #else GTK_WIDGET_SET_FLAGS(widget, GTK_MAPPED); + #endif + #if GTK_CHECK_VERSION(3,0,0) + gdk_window_show(gtk_widget_get_window(widget)); + #else gdk_window_show(widget->window); + #endif gdk_window_show(form->bin_window); for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next) { GtkFormChild *child = tmp_list->data; + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_visible(child->widget) + && !gtk_widget_get_mapped(child->widget)) + #else if (GTK_WIDGET_VISIBLE(child->widget) && !GTK_WIDGET_MAPPED(child->widget)) + #endif gtk_widget_map(child->widget); } } *************** *** 369,380 **** --- 503,523 ---- if (child->window != NULL) { + #if GTK_CHECK_VERSION(3,0,0) + g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget), + G_CALLBACK(gtk_form_child_map), + child); + g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget), + G_CALLBACK(gtk_form_child_unmap), + child); + #else gtk_signal_disconnect_by_func(GTK_OBJECT(child->widget), GTK_SIGNAL_FUNC(gtk_form_child_map), child); gtk_signal_disconnect_by_func(GTK_OBJECT(child->widget), GTK_SIGNAL_FUNC(gtk_form_child_unmap), child); + #endif gdk_window_set_user_data(child->window, NULL); gdk_window_destroy(child->window); *************** *** 385,404 **** --- 528,560 ---- tmp_list = tmp_list->next; } + #if GTK_CHECK_VERSION(3,0,0) + if (GTK_WIDGET_CLASS (gtk_form_parent_class)->unrealize) + (* GTK_WIDGET_CLASS (gtk_form_parent_class)->unrealize) (widget); + #else if (GTK_WIDGET_CLASS (parent_class)->unrealize) (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); + #endif } static void gtk_form_size_request(GtkWidget *widget, GtkRequisition *requisition) { + #if !GTK_CHECK_VERSION(3,0,0) GList *tmp_list; GtkForm *form; + #endif g_return_if_fail(GTK_IS_FORM(widget)); + #if !GTK_CHECK_VERSION(3,0,0) form = GTK_FORM(widget); + #endif + #if GTK_CHECK_VERSION(3,0,0) + requisition->width = 1; + requisition->height = 1; + #else requisition->width = form->width; requisition->height = form->height; *************** *** 410,416 **** --- 566,601 ---- gtk_widget_size_request(child->widget, NULL); tmp_list = tmp_list->next; } + #endif + } + + #if GTK_CHECK_VERSION(3,0,0) + static void + gtk_form_get_preferred_width(GtkWidget *widget, + gint *minimal_width, + gint *natural_width) + { + GtkRequisition requisition; + + gtk_form_size_request(widget, &requisition); + + *minimal_width = requisition.width; + *natural_width = requisition.width; + } + + static void + gtk_form_get_preferred_height(GtkWidget *widget, + gint *minimal_height, + gint *natural_height) + { + GtkRequisition requisition; + + gtk_form_size_request(widget, &requisition); + + *minimal_height = requisition.height; + *natural_height = requisition.height; } + #endif /* GTK_CHECK_VERSION(3,0,0) */ static void gtk_form_size_allocate(GtkWidget *widget, GtkAllocation *allocation) *************** *** 418,434 **** --- 603,636 ---- GList *tmp_list; GtkForm *form; gboolean need_reposition; + #if GTK_CHECK_VERSION(3,0,0) + GtkAllocation cur_alloc; + #endif g_return_if_fail(GTK_IS_FORM(widget)); + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_get_allocation(widget, &cur_alloc); + + if (cur_alloc.x == allocation->x + && cur_alloc.y == allocation->y + && cur_alloc.width == allocation->width + && cur_alloc.height == allocation->height) + #else if (widget->allocation.x == allocation->x && widget->allocation.y == allocation->y && widget->allocation.width == allocation->width && widget->allocation.height == allocation->height) + #endif return; + #if GTK_CHECK_VERSION(3,0,0) + need_reposition = cur_alloc.width != allocation->width + || cur_alloc.height != allocation->height; + #else need_reposition = widget->allocation.width != allocation->width || widget->allocation.height != allocation->height; + #endif form = GTK_FORM(widget); if (need_reposition) *************** *** 444,463 **** --- 646,726 ---- } } + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_realized(widget)) + #else if (GTK_WIDGET_REALIZED(widget)) + #endif { + #if GTK_CHECK_VERSION(3,0,0) + gdk_window_move_resize(gtk_widget_get_window(widget), + allocation->x, allocation->y, + allocation->width, allocation->height); + #else gdk_window_move_resize(widget->window, allocation->x, allocation->y, allocation->width, allocation->height); + #endif gdk_window_move_resize(GTK_FORM(widget)->bin_window, 0, 0, allocation->width, allocation->height); } + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_allocation(widget, allocation); + #else widget->allocation = *allocation; + #endif if (need_reposition) gtk_form_send_configure(form); } + #if GTK_CHECK_VERSION(3,0,0) + static void + gtk_form_render_background(GtkWidget *widget, cairo_t *cr) + { + gtk_render_background(gtk_widget_get_style_context(widget), cr, + 0, 0, + gtk_widget_get_allocated_width(widget), + gtk_widget_get_allocated_height(widget)); + } + + static gboolean + gtk_form_draw(GtkWidget *widget, cairo_t *cr) + { + GList *tmp_list = NULL; + GtkForm *form = NULL; + + g_return_val_if_fail(GTK_IS_FORM(widget), FALSE); + + gtk_form_render_background(widget, cr); + + form = GTK_FORM(widget); + for (tmp_list = form->children; tmp_list; tmp_list = tmp_list->next) + { + GtkFormChild * const formchild = tmp_list->data; + + if (!gtk_widget_get_has_window(formchild->widget) && + gtk_cairo_should_draw_window(cr, formchild->window)) + { + /* To get gtk_widget_draw() to work, it is required to call + * gtk_widget_size_allocate() in advance with a well-posed + * allocation for a given child widget in order to set a + * certain private GtkWidget variable, called + * widget->priv->alloc_need, to the proper value; othewise, + * gtk_widget_draw() fails and the relevant scrollbar won't + * appear on the screen. + * + * Calling gtk_form_position_child() like this is one of ways + * to make sure of that. */ + gtk_form_position_child(form, formchild, TRUE); + + gtk_form_render_background(formchild->widget, cr); + } + } + + return GTK_WIDGET_CLASS(gtk_form_parent_class)->draw(widget, cr); + } + #else /* !GTK_CHECK_VERSION(3,0,0) */ static gint gtk_form_expose(GtkWidget *widget, GdkEventExpose *event) { *************** *** 497,502 **** --- 760,766 ---- return FALSE; } + #endif /* !GTK_CHECK_VERSION(3,0,0) */ /* Container method */ *************** *** 522,533 **** --- 786,807 ---- if (tmp_list) { + #if GTK_CHECK_VERSION(3,0,0) + const gboolean was_visible = gtk_widget_get_visible(widget); + #endif if (child->window) { + #if GTK_CHECK_VERSION(3,0,0) + g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget), + G_CALLBACK(>k_form_child_map), child); + g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget), + G_CALLBACK(>k_form_child_unmap), child); + #else gtk_signal_disconnect_by_func(GTK_OBJECT(child->widget), GTK_SIGNAL_FUNC(>k_form_child_map), child); gtk_signal_disconnect_by_func(GTK_OBJECT(child->widget), GTK_SIGNAL_FUNC(>k_form_child_unmap), child); + #endif /* FIXME: This will cause problems for reparenting NO_WINDOW * widgets out of a GtkForm *************** *** 536,542 **** gdk_window_destroy(child->window); } gtk_widget_unparent(widget); ! form->children = g_list_remove_link(form->children, tmp_list); g_list_free_1(tmp_list); g_free(child); --- 810,819 ---- gdk_window_destroy(child->window); } gtk_widget_unparent(widget); ! #if GTK_CHECK_VERSION(3,0,0) ! if (was_visible) ! gtk_widget_queue_resize(GTK_WIDGET(container)); ! #endif form->children = g_list_remove_link(form->children, tmp_list); g_list_free_1(tmp_list); g_free(child); *************** *** 577,583 **** --- 854,864 ---- if (child->window != NULL) return; /* been there, done that */ + #if GTK_CHECK_VERSION(3,0,0) + if (!gtk_widget_get_has_window(child->widget)) + #else if (GTK_WIDGET_NO_WINDOW(child->widget)) + #endif { GtkWidget *widget; GdkWindowAttr attributes; *************** *** 588,621 **** --- 869,943 ---- attributes.window_type = GDK_WINDOW_CHILD; attributes.x = child->x; attributes.y = child->y; + #if GTK_CHECK_VERSION(3,0,0) + { + GtkRequisition requisition; + + gtk_widget_get_preferred_size(child->widget, &requisition, NULL); + + attributes.width = requisition.width; + attributes.height = requisition.height; + } + #else attributes.width = child->widget->requisition.width; attributes.height = child->widget->requisition.height; + #endif attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual(widget); + #if !GTK_CHECK_VERSION(3,0,0) attributes.colormap = gtk_widget_get_colormap(widget); + #endif attributes.event_mask = GDK_EXPOSURE_MASK; + #if GTK_CHECK_VERSION(3,0,0) + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; + #else attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + #endif child->window = gdk_window_new(form->bin_window, &attributes, attributes_mask); gdk_window_set_user_data(child->window, widget); + #if GTK_CHECK_VERSION(3,0,0) + { + GtkStyleContext * const sctx = gtk_widget_get_style_context(widget); + + gtk_style_context_set_state(sctx, GTK_STATE_FLAG_NORMAL); + # if !GTK_CHECK_VERSION(3,18,0) + gtk_style_context_set_background(sctx, child->window); + # endif + } + #else gtk_style_set_background(widget->style, child->window, GTK_STATE_NORMAL); + #endif gtk_widget_set_parent_window(child->widget, child->window); + #if !GTK_CHECK_VERSION(3,16,0) gtk_form_set_static_gravity(child->window, TRUE); + #endif /* * Install signal handlers to map/unmap child->window * alongside with the actual widget. */ + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(child->widget), "map", + G_CALLBACK(>k_form_child_map), child); + g_signal_connect(G_OBJECT(child->widget), "unmap", + G_CALLBACK(>k_form_child_unmap), child); + #else gtk_signal_connect(GTK_OBJECT(child->widget), "map", GTK_SIGNAL_FUNC(>k_form_child_map), child); gtk_signal_connect(GTK_OBJECT(child->widget), "unmap", GTK_SIGNAL_FUNC(>k_form_child_unmap), child); + #endif } + #if GTK_CHECK_VERSION(3,0,0) + else if (!gtk_widget_get_realized(child->widget)) + #else else if (!GTK_WIDGET_REALIZED(child->widget)) + #endif { gtk_widget_set_parent_window(child->widget, form->bin_window); } *************** *** 627,634 **** --- 949,962 ---- gtk_form_attach_child_window(form, child); gtk_widget_realize(child->widget); + #if !GTK_CHECK_VERSION(3,16,0) if (child->window == NULL) /* might be already set, see above */ + # if GTK_CHECK_VERSION(3,0,0) + gtk_form_set_static_gravity(gtk_widget_get_window(child->widget), TRUE); + # else gtk_form_set_static_gravity(child->widget->window, TRUE); + # endif + #endif } static void *************** *** 646,654 **** --- 974,991 ---- { if (!child->mapped) { + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_mapped(GTK_WIDGET(form)) + && gtk_widget_get_visible(child->widget)) + #else if (GTK_WIDGET_MAPPED(form) && GTK_WIDGET_VISIBLE(child->widget)) + #endif { + #if GTK_CHECK_VERSION(3,0,0) + if (!gtk_widget_get_mapped(child->widget)) + #else if (!GTK_WIDGET_MAPPED(child->widget)) + #endif gtk_widget_map(child->widget); child->mapped = TRUE; *************** *** 659,673 **** --- 996,1026 ---- if (force_allocate) { GtkAllocation allocation; + #if GTK_CHECK_VERSION(3,0,0) + GtkRequisition requisition; + gtk_widget_get_preferred_size(child->widget, &requisition, NULL); + #endif + + #if GTK_CHECK_VERSION(3,0,0) + if (!gtk_widget_get_has_window(child->widget)) + #else if (GTK_WIDGET_NO_WINDOW(child->widget)) + #endif { if (child->window) { + #if GTK_CHECK_VERSION(3,0,0) + gdk_window_move_resize(child->window, + x, y, + requisition.width, + requisition.height); + #else gdk_window_move_resize(child->window, x, y, child->widget->requisition.width, child->widget->requisition.height); + #endif } allocation.x = 0; *************** *** 679,686 **** --- 1032,1044 ---- allocation.y = y; } + #if GTK_CHECK_VERSION(3,0,0) + allocation.width = requisition.width; + allocation.height = requisition.height; + #else allocation.width = child->widget->requisition.width; allocation.height = child->widget->requisition.height; + #endif gtk_widget_size_allocate(child->widget, &allocation); } *************** *** 691,697 **** --- 1049,1059 ---- { child->mapped = FALSE; + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_mapped(child->widget)) + #else if (GTK_WIDGET_MAPPED(child->widget)) + #endif gtk_widget_unmap(child->widget); } } *************** *** 717,722 **** --- 1079,1085 ---- * them or discards them, depending on whether we are obscured * or not. */ + #if !GTK_CHECK_VERSION(3,0,0) static GdkFilterReturn gtk_form_filter(GdkXEvent *gdk_xevent, GdkEvent *event UNUSED, gpointer data) { *************** *** 783,789 **** --- 1146,1154 ---- } return GDK_FILTER_CONTINUE; } + #endif /* !GTK_CHECK_VERSION(3,0,0) */ + #if !GTK_CHECK_VERSION(3,16,0) static void gtk_form_set_static_gravity(GdkWindow *window, gboolean use_static) { *************** *** 791,803 **** --- 1156,1173 ---- * results in an annoying assertion error message. */ gdk_window_set_static_gravities(window, use_static); } + #endif /* !GTK_CHECK_VERSION(3,16,0) */ void gtk_form_move_resize(GtkForm *form, GtkWidget *widget, gint x, gint y, gint w, gint h) { + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_size_request(widget, w, h); + #else widget->requisition.width = w; widget->requisition.height = h; + #endif gtk_form_move(form, widget, x, y); } *************** *** 811,821 **** --- 1181,1204 ---- widget = GTK_WIDGET(form); event.type = GDK_CONFIGURE; + #if GTK_CHECK_VERSION(3,0,0) + event.window = gtk_widget_get_window(widget); + { + GtkAllocation allocation; + + gtk_widget_get_allocation(widget, &allocation); + event.x = allocation.x; + event.y = allocation.y; + event.width = allocation.width; + event.height = allocation.height; + } + #else event.window = widget->window; event.x = widget->allocation.x; event.y = widget->allocation.y; event.width = widget->allocation.width; event.height = widget->allocation.height; + #endif gtk_main_do_event((GdkEvent*)&event); } *************** *** 841,844 **** child->mapped = FALSE; gdk_window_hide(child->window); } - --- 1224,1226 ---- *** ../vim-7.4.1401/src/gui_gtk_f.h 2010-06-25 04:51:05.000000000 +0200 --- src/gui_gtk_f.h 2016-02-23 16:37:09.232080022 +0100 *************** *** 9,16 **** --- 9,20 ---- #ifndef __GTK_FORM_H__ #define __GTK_FORM_H__ + #ifdef USE_GTK3 + #include + #else #include #include + #endif #ifdef __cplusplus *************** *** 18,27 **** --- 22,38 ---- #endif #define GTK_TYPE_FORM (gtk_form_get_type ()) + #ifdef USE_GTK3 + #define GTK_FORM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_FORM, GtkForm)) + #define GTK_FORM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_FORM, GtkFormClass)) + #define GTK_IS_FORM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_FORM)) + #define GTK_IS_FORM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_FORM)) + #else #define GTK_FORM(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_FORM, GtkForm)) #define GTK_FORM_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_FORM, GtkFormClass)) #define GTK_IS_FORM(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_FORM)) #define GTK_IS_FORM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FORM)) + #endif typedef struct _GtkForm GtkForm; *************** *** 33,45 **** --- 44,60 ---- GList *children; + #ifndef USE_GTK3 guint width; guint height; + #endif GdkWindow *bin_window; + #ifndef USE_GTK3 GdkVisibilityState visibility; gulong configure_serial; + #endif gint freeze_count; }; *************** *** 49,55 **** --- 64,74 ---- GtkContainerClass parent_class; }; + #ifdef USE_GTK3 + GType gtk_form_get_type(void); + #else GtkType gtk_form_get_type(void); + #endif GtkWidget *gtk_form_new(void); *** ../vim-7.4.1401/src/gui_gtk_x11.c 2016-02-01 21:40:10.997782016 +0100 --- src/gui_gtk_x11.c 2016-02-23 16:45:12.131035030 +0100 *************** *** 19,24 **** --- 19,28 ---- * * (C) 2002,2003 Jason Hildebrand * Daniel Elstner + * + * Support for GTK+ 3 was added by: + * + * 2016 Kazunobu Kuriyama */ #include "vim.h" *************** *** 75,88 **** # define GdkEventConfigure int # define GdkEventClient int #else ! # include # include # ifdef WIN3264 # include # else # include # endif - # include # include "gui_gtk_f.h" #endif --- 79,96 ---- # define GdkEventConfigure int # define GdkEventClient int #else ! # if GTK_CHECK_VERSION(3,0,0) ! # include ! # include ! # else ! # include ! # endif # include # ifdef WIN3264 # include # else # include # endif # include # include "gui_gtk_f.h" #endif *************** *** 580,585 **** --- 588,594 ---- } #endif + #if !GTK_CHECK_VERSION(3,0,0) /* * This should be maybe completely removed. * Doesn't seem possible, since check_copy_area() relies on *************** *** 601,610 **** --- 610,702 ---- gui.visibility != GDK_VISIBILITY_UNOBSCURED); return FALSE; } + #endif /* !GTK_CHECK_VERSION(3,0,0) */ /* * Redraw the corresponding portions of the screen. */ + #if GTK_CHECK_VERSION(3,0,0) + static gboolean is_key_pressed = FALSE; + + static gboolean gui_gtk_is_blink_on(void); + static gboolean gui_gtk_is_no_blink(void); + static void gui_gtk_window_clear(GdkWindow *win); + + static void + gui_gtk3_redraw(int x, int y, int width, int height) + { + gui_redraw_block(Y_2_ROW(y), X_2_COL(x), + Y_2_ROW(y + height - 1), X_2_COL(x + width - 1), + GUI_MON_NOCLEAR); + } + + static void + gui_gtk3_update_cursor(cairo_t *cr) + { + if (gui.row == gui.cursor_row) + { + gui.by_signal = TRUE; + gui_update_cursor(TRUE, TRUE); + gui.by_signal = FALSE; + cairo_paint(cr); + } + } + + static gboolean + gui_gtk3_should_draw_cursor(void) + { + unsigned int cond = 0; + cond |= gui_gtk_is_blink_on(); + cond |= is_key_pressed; + cond |= gui.in_focus == FALSE; + cond |= gui_gtk_is_no_blink(); + return cond; + } + + static gboolean + draw_event(GtkWidget *widget, + cairo_t *cr, + gpointer user_data UNUSED) + { + /* Skip this when the GUI isn't set up yet, will redraw later. */ + if (gui.starting) + return FALSE; + + out_flush(); /* make sure all output has been processed */ + /* for GTK+ 3, may induce other draw events. */ + + cairo_set_source_surface(cr, gui.surface, 0, 0); + + /* Draw the window without the cursor. */ + gui.by_signal = TRUE; + { + cairo_rectangle_list_t *list = NULL; + + gui_gtk_window_clear(gtk_widget_get_window(widget)); + + list = cairo_copy_clip_rectangle_list(cr); + if (list->status != CAIRO_STATUS_CLIP_NOT_REPRESENTABLE) + { + int i; + for (i = 0; i < list->num_rectangles; i++) + { + const cairo_rectangle_t rect = list->rectangles[i]; + gui_gtk3_redraw(rect.x, rect.y, rect.width, rect.height); + } + } + cairo_rectangle_list_destroy(list); + + cairo_paint(cr); + } + gui.by_signal = FALSE; + + /* Add the cursor to the window if necessary.*/ + if (gui_gtk3_should_draw_cursor()) + gui_gtk3_update_cursor(cr); + + return FALSE; + } + #else /* !GTK_CHECK_VERSION(3,0,0) */ static gint expose_event(GtkWidget *widget UNUSED, GdkEventExpose *event, *************** *** 631,636 **** --- 723,729 ---- return FALSE; } + #endif /* !GTK_CHECK_VERSION(3,0,0) */ #ifdef FEAT_CLIENTSERVER /* *************** *** 643,649 **** --- 736,746 ---- { if (event->type == GDK_PROPERTY_NOTIFY && event->state == (int)GDK_PROPERTY_NEW_VALUE + # if GTK_CHECK_VERSION(3,0,0) + && GDK_WINDOW_XID(event->window) == commWindow + # else && GDK_WINDOW_XWINDOW(event->window) == commWindow + # endif && GET_X_ATOM(event->atom) == commProperty) { XEvent xev; *************** *** 653,663 **** xev.xproperty.atom = commProperty; xev.xproperty.window = commWindow; xev.xproperty.state = PropertyNewValue; serverEventProc(GDK_WINDOW_XDISPLAY(widget->window), &xev, 0); } return FALSE; } ! #endif /**************************************************************************** --- 750,765 ---- xev.xproperty.atom = commProperty; xev.xproperty.window = commWindow; xev.xproperty.state = PropertyNewValue; + # if GTK_CHECK_VERSION(3,0,0) + serverEventProc(GDK_WINDOW_XDISPLAY(gtk_widget_get_window(widget)), + &xev, 0); + # else serverEventProc(GDK_WINDOW_XDISPLAY(widget->window), &xev, 0); + # endif } return FALSE; } ! #endif /* defined(FEAT_CLIENTSERVER) */ /**************************************************************************** *************** *** 682,687 **** --- 784,803 ---- static long_u blink_offtime = 250; static guint blink_timer = 0; + #if GTK_CHECK_VERSION(3,0,0) + static gboolean + gui_gtk_is_blink_on(void) + { + return blink_state == BLINK_ON; + } + + static gboolean + gui_gtk_is_no_blink(void) + { + return blink_waittime == 0 || blink_ontime == 0 || blink_offtime == 0; + } + #endif + void gui_mch_set_blinking(long waittime, long on, long off) { *************** *** 698,704 **** --- 814,824 ---- { if (blink_timer) { + #if GTK_CHECK_VERSION(3,0,0) + g_source_remove(blink_timer); + #else gtk_timeout_remove(blink_timer); + #endif blink_timer = 0; } if (blink_state == BLINK_OFF) *************** *** 706,727 **** --- 826,861 ---- blink_state = BLINK_NONE; } + #if GTK_CHECK_VERSION(3,0,0) + static gboolean + #else static gint + #endif blink_cb(gpointer data UNUSED) { if (blink_state == BLINK_ON) { gui_undraw_cursor(); blink_state = BLINK_OFF; + #if GTK_CHECK_VERSION(3,0,0) + blink_timer = g_timeout_add((guint)blink_offtime, + (GSourceFunc) blink_cb, NULL); + #else blink_timer = gtk_timeout_add((guint32)blink_offtime, (GtkFunction) blink_cb, NULL); + #endif } else { gui_update_cursor(TRUE, FALSE); blink_state = BLINK_ON; + #if GTK_CHECK_VERSION(3,0,0) + blink_timer = g_timeout_add((guint)blink_ontime, + (GSourceFunc) blink_cb, NULL); + #else blink_timer = gtk_timeout_add((guint32)blink_ontime, (GtkFunction) blink_cb, NULL); + #endif } return FALSE; /* don't happen again */ *************** *** 736,749 **** --- 870,892 ---- { if (blink_timer) { + #if GTK_CHECK_VERSION(3,0,0) + g_source_remove(blink_timer); + #else gtk_timeout_remove(blink_timer); + #endif blink_timer = 0; } /* Only switch blinking on if none of the times is zero */ if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus) { + #if GTK_CHECK_VERSION(3,0,0) + blink_timer = g_timeout_add((guint)blink_waittime, + (GSourceFunc) blink_cb, NULL); + #else blink_timer = gtk_timeout_add((guint32)blink_waittime, (GtkFunction) blink_cb, NULL); + #endif blink_state = BLINK_ON; gui_update_cursor(TRUE, FALSE); } *************** *** 758,764 **** --- 901,911 ---- gui_mch_start_blink(); /* make sure keyboard input goes there */ + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_socket_id == 0 || !gtk_widget_has_focus(gui.drawarea)) + #else if (gtk_socket_id == 0 || !GTK_WIDGET_HAS_FOCUS(gui.drawarea)) + #endif gtk_widget_grab_focus(gui.drawarea); return FALSE; *************** *** 938,943 **** --- 1085,1095 ---- guint state; char_u *s, *d; + #if GTK_CHECK_VERSION(3,0,0) + is_key_pressed = TRUE; + gui_mch_stop_blink(); + #endif + gui.event_time = event->time; key_sym = event->keyval; state = event->state; *************** *** 1127,1138 **** return TRUE; } ! #if defined(FEAT_XIM) static gboolean key_release_event(GtkWidget *widget UNUSED, GdkEventKey *event, gpointer data UNUSED) { gui.event_time = event->time; /* * GTK+ 2 input methods may do fancy stuff on key release events too. --- 1279,1295 ---- return TRUE; } ! #if defined(FEAT_XIM) || GTK_CHECK_VERSION(3,0,0) static gboolean key_release_event(GtkWidget *widget UNUSED, GdkEventKey *event, gpointer data UNUSED) { + # if GTK_CHECK_VERSION(3,0,0) + is_key_pressed = FALSE; + gui_mch_start_blink(); + # endif + # if defined(FEAT_XIM) gui.event_time = event->time; /* * GTK+ 2 input methods may do fancy stuff on key release events too. *************** *** 1140,1145 **** --- 1297,1305 ---- * by holding down CTRL-SHIFT and typing hexadecimal digits. */ return xim_queue_key_press_event(event, FALSE); + # else + return TRUE; + # endif } #endif *************** *** 1179,1191 **** --- 1339,1360 ---- int len; int motion_type = MAUTO; + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_selection_data_get_selection(data) == clip_plus.gtk_sel_atom) + #else if (data->selection == clip_plus.gtk_sel_atom) + #endif cbd = &clip_plus; else cbd = &clip_star; + #if GTK_CHECK_VERSION(3,0,0) + text = (char_u *)gtk_selection_data_get_data(data); + len = gtk_selection_data_get_length(data); + #else text = (char_u *)data->data; len = data->length; + #endif if (text == NULL || len <= 0) { *************** *** 1195,1207 **** return; } if (data->type == vim_atom) { motion_type = *text++; --len; } ! else if (data->type == vimenc_atom) { char_u *enc; vimconv_T conv; --- 1364,1383 ---- return; } + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_selection_data_get_data_type(data) == vim_atom) + #else if (data->type == vim_atom) + #endif { motion_type = *text++; --len; } ! #if GTK_CHECK_VERSION(3,0,0) ! else if (gtk_selection_data_get_data_type(data) == vimenc_atom) ! #else else if (data->type == vimenc_atom) + #endif { char_u *enc; vimconv_T conv; *************** *** 1292,1298 **** --- 1468,1479 ---- GdkAtom type; VimClipboard *cbd; + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_selection_data_get_selection(selection_data) + == clip_plus.gtk_sel_atom) + #else if (selection_data->selection == clip_plus.gtk_sel_atom) + #endif cbd = &clip_plus; else cbd = &clip_star; *************** *** 1361,1368 **** --- 1542,1553 ---- string = tmpbuf; length += 2; + #if !GTK_CHECK_VERSION(3,0,0) + /* Looks redandunt even for GTK2 because these values are + * overwritten by gtk_selection_data_set() that follows. */ selection_data->type = selection_data->target; selection_data->format = 16; /* 16 bits per char */ + #endif gtk_selection_data_set(selection_data, html_atom, 16, string, length); vim_free(string); *************** *** 1411,1419 **** if (string != NULL) { selection_data->type = selection_data->target; selection_data->format = 8; /* 8 bits per char */ ! gtk_selection_data_set(selection_data, type, 8, string, length); vim_free(string); } --- 1596,1607 ---- if (string != NULL) { + #if !GTK_CHECK_VERSION(3,0,0) + /* Looks redandunt even for GTK2 because these values are + * overwritten by gtk_selection_data_set() that follows. */ selection_data->type = selection_data->target; selection_data->format = 8; /* 8 bits per char */ ! #endif gtk_selection_data_set(selection_data, type, 8, string, length); vim_free(string); } *************** *** 1493,1499 **** --- 1681,1691 ---- /* * Timer used to recognize multiple clicks of the mouse button */ + #if GTK_CHECK_VERSION(3,0,0) + static gboolean + #else static gint + #endif mouse_click_timer_cb(gpointer data) { /* we don't use this information currently */ *************** *** 1505,1517 **** --- 1697,1716 ---- static guint motion_repeat_timer = 0; static int motion_repeat_offset = FALSE; + #ifdef GTK_DEST_DEFAULT_ALL + static gboolean motion_repeat_timer_cb(gpointer); + #else static gint motion_repeat_timer_cb(gpointer); + #endif static void process_motion_notify(int x, int y, GdkModifierType state) { int button; int_u vim_modifiers; + #if GTK_CHECK_VERSION(3,0,0) + GtkAllocation allocation; + #endif button = (state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | *************** *** 1538,1546 **** --- 1737,1753 ---- /* * Auto repeat timer handling. */ + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_get_allocation(gui.drawarea, &allocation); + + if (x < 0 || y < 0 + || x >= allocation.width + || y >= allocation.height) + #else if (x < 0 || y < 0 || x >= gui.drawarea->allocation.width || y >= gui.drawarea->allocation.height) + #endif { int dx; *************** *** 1551,1558 **** --- 1758,1770 ---- /* Calculate the maximal distance of the cursor from the drawing area. * (offshoot can't become negative here!). */ + #if GTK_CHECK_VERSION(3,0,0) + dx = x < 0 ? -x : x - allocation.width; + dy = y < 0 ? -y : y - allocation.height; + #else dx = x < 0 ? -x : x - gui.drawarea->allocation.width; dy = y < 0 ? -y : y - gui.drawarea->allocation.height; + #endif offshoot = dx > dy ? dx : dy; *************** *** 1577,1598 **** --- 1789,1854 ---- /* shoot again */ if (!motion_repeat_timer) + #if GTK_CHECK_VERSION(3,0,0) + motion_repeat_timer = g_timeout_add((guint)delay, + motion_repeat_timer_cb, NULL); + #else motion_repeat_timer = gtk_timeout_add((guint32)delay, motion_repeat_timer_cb, NULL); + #endif } } + #if GTK_CHECK_VERSION(3,0,0) + static GdkDevice * + gui_gtk_get_pointer_device(GtkWidget *widget) + { + 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); + return gdk_device_manager_get_client_pointer(mngr); + } + + static GdkWindow * + gui_gtk_get_pointer(GtkWidget *widget, + gint *x, + gint *y, + GdkModifierType *state) + { + GdkWindow * const win = gtk_widget_get_window(widget); + GdkDevice * const dev = gui_gtk_get_pointer_device(widget); + return gdk_window_get_device_position(win, dev , x, y, state); + } + + static GdkWindow * + gui_gtk_window_at_position(GtkWidget *widget, + gint *x, + gint *y) + { + GdkDevice * const dev = gui_gtk_get_pointer_device(widget); + return gdk_device_get_window_at_position(dev, x, y); + } + #endif + /* * Timer used to recognize multiple clicks of the mouse button. */ + #if GTK_CHECK_VERSION(3,0,0) + static gboolean + #else static gint + #endif motion_repeat_timer_cb(gpointer data UNUSED) { int x; int y; GdkModifierType state; + #if GTK_CHECK_VERSION(3,0,0) + gui_gtk_get_pointer(gui.drawarea, &x, &y, &state); + #else gdk_window_get_pointer(gui.drawarea->window, &x, &y, &state); + #endif if (!(state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | *************** *** 1637,1643 **** --- 1893,1903 ---- int y; GdkModifierType state; + #if GTK_CHECK_VERSION(3,0,0) + gui_gtk_get_pointer(widget, &x, &y, &state); + #else gdk_window_get_pointer(widget->window, &x, &y, &state); + #endif process_motion_notify(x, y, state); } else *************** *** 1668,1674 **** --- 1928,1938 ---- gui.event_time = event->time; /* Make sure we have focus now we've been selected */ + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_socket_id != 0 && !gtk_widget_has_focus(widget)) + #else if (gtk_socket_id != 0 && !GTK_WIDGET_HAS_FOCUS(widget)) + #endif gtk_widget_grab_focus(widget); /* *************** *** 1684,1697 **** --- 1948,1970 ---- /* Handle multiple clicks */ if (!mouse_timed_out && mouse_click_timer) { + #if GTK_CHECK_VERSION(3,0,0) + g_source_remove(mouse_click_timer); + #else gtk_timeout_remove(mouse_click_timer); + #endif mouse_click_timer = 0; repeated_click = TRUE; } mouse_timed_out = FALSE; + #if GTK_CHECK_VERSION(3,0,0) + mouse_click_timer = g_timeout_add((guint)p_mouset, + mouse_click_timer_cb, &mouse_timed_out); + #else mouse_click_timer = gtk_timeout_add((guint32)p_mouset, mouse_click_timer_cb, &mouse_timed_out); + #endif switch (event->button) { *************** *** 1730,1736 **** --- 2003,2013 ---- int button; int_u vim_modifiers; + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_socket_id != 0 && !gtk_widget_has_focus(widget)) + #else if (gtk_socket_id != 0 && !GTK_WIDGET_HAS_FOCUS(widget)) + #endif gtk_widget_grab_focus(widget); switch (event->direction) *************** *** 1781,1787 **** --- 2058,2068 ---- area .*/ if (motion_repeat_timer) { + #if GTK_CHECK_VERSION(3,0,0) + g_source_remove(motion_repeat_timer); + #else gtk_timeout_remove(motion_repeat_timer); + #endif motion_repeat_timer = 0; } *************** *** 1896,1902 **** --- 2177,2189 ---- char_u **fnames; int nfiles = 0; + # if GTK_CHECK_VERSION(3,0,0) + fnames = parse_uri_list(&nfiles, + (char_u *)gtk_selection_data_get_data(data), + gtk_selection_data_get_length(data)); + # else fnames = parse_uri_list(&nfiles, data->data, data->length); + # endif if (fnames != NULL && nfiles > 0) { *************** *** 1923,1932 **** --- 2210,2228 ---- int len; char_u *tmpbuf = NULL; + # if GTK_CHECK_VERSION(3,0,0) + text = (char_u *)gtk_selection_data_get_data(data); + len = gtk_selection_data_get_length(data); + # else text = data->data; len = data->length; + # endif + # if GTK_CHECK_VERSION(3,0,0) + if (gtk_selection_data_get_data_type(data) == utf8_string_atom) + # else if (data->type == utf8_string_atom) + # endif { if (input_conv.vc_type != CONV_NONE) tmpbuf = string_convert(&input_conv, text, &len); *************** *** 1962,1971 **** --- 2258,2278 ---- GdkModifierType state; /* Guard against trash */ + # if GTK_CHECK_VERSION(3,0,0) + const guchar * const data_data = gtk_selection_data_get_data(data); + const gint data_length = gtk_selection_data_get_length(data); + const gint data_format = gtk_selection_data_get_format(data); + + if (data_data == NULL + || data_length <= 0 + || data_format != 8 + || data_data[data_length] != '\0') + # else if (data->data == NULL || data->length <= 0 || data->format != 8 || data->data[data->length] != '\0') + # endif { gtk_drag_finish(context, FALSE, FALSE, time_); return; *************** *** 1973,1979 **** --- 2280,2290 ---- /* Get the current modifier state for proper distinguishment between * different operations later. */ + #if GTK_CHECK_VERSION(3,0,0) + gui_gtk_get_pointer(widget, NULL, NULL, &state); + # else gdk_window_get_pointer(widget->window, NULL, NULL, &state); + # endif /* Not sure about the role of "text/plain" here... */ if (info == (guint)TARGET_TEXT_URI_LIST) *************** *** 2253,2259 **** Atom *existing_atoms = NULL; int count = 0; ! #ifdef USE_XSMP if (xsmp_icefd != -1) { /* --- 2564,2570 ---- Atom *existing_atoms = NULL; int count = 0; ! # ifdef USE_XSMP if (xsmp_icefd != -1) { /* *************** *** 2264,2279 **** g_io_add_watch(g_io, G_IO_IN | G_IO_ERR | G_IO_HUP, local_xsmp_handle_requests, (gpointer)g_io); } else ! #endif { /* Fall back to old method */ /* first get the existing value */ if (XGetWMProtocols(GDK_WINDOW_XDISPLAY(gui.mainwin->window), GDK_WINDOW_XWINDOW(gui.mainwin->window), &existing_atoms, &count)) { Atom *new_atoms; Atom save_yourself_xatom; --- 2575,2599 ---- g_io_add_watch(g_io, G_IO_IN | G_IO_ERR | G_IO_HUP, local_xsmp_handle_requests, (gpointer)g_io); + g_io_channel_unref(g_io); } else ! # endif { /* Fall back to old method */ /* first get the existing value */ + # if GTK_CHECK_VERSION(3,0,0) + GdkWindow * const mainwin_win = gtk_widget_get_window(gui.mainwin); + + if (XGetWMProtocols(GDK_WINDOW_XDISPLAY(mainwin_win), + GDK_WINDOW_XID(mainwin_win), + &existing_atoms, &count)) + # else if (XGetWMProtocols(GDK_WINDOW_XDISPLAY(gui.mainwin->window), GDK_WINDOW_XWINDOW(gui.mainwin->window), &existing_atoms, &count)) + # endif { Atom *new_atoms; Atom save_yourself_xatom; *************** *** 2295,2302 **** --- 2615,2627 ---- { memcpy(new_atoms, existing_atoms, count * sizeof(Atom)); new_atoms[count] = save_yourself_xatom; + # if GTK_CHECK_VERSION(3,0,0) + XSetWMProtocols(GDK_WINDOW_XDISPLAY(mainwin_win), + GDK_WINDOW_XID(mainwin_win), + # else XSetWMProtocols(GDK_WINDOW_XDISPLAY(gui.mainwin->window), GDK_WINDOW_XWINDOW(gui.mainwin->window), + # endif new_atoms, count + 1); vim_free(new_atoms); } *************** *** 2341,2348 **** --- 2666,2678 ---- * know we are done saving ourselves. We don't want to be * restarted, thus set argv to NULL. */ + # if GTK_CHECK_VERSION(3,0,0) + XSetCommand(GDK_WINDOW_XDISPLAY(gtk_widget_get_window(gui.mainwin)), + GDK_WINDOW_XID(gtk_widget_get_window(gui.mainwin)), + # else XSetCommand(GDK_WINDOW_XDISPLAY(gui.mainwin->window), GDK_WINDOW_XWINDOW(gui.mainwin->window), + # endif NULL, 0); return GDK_FILTER_REMOVE; } *************** *** 2376,2385 **** --- 2706,2723 ---- #undef magick # undef static + #if GTK_CHECK_VERSION(3,0,0) + GdkWindow * const mainwin_win = gtk_widget_get_window(gui.mainwin); + #endif + /* When started with "--echo-wid" argument, write window ID on stdout. */ if (echo_wid_arg) { + #if GTK_CHECK_VERSION(3,0,0) + printf("WID: %ld\n", (long)GDK_WINDOW_XID(mainwin_win)); + #else printf("WID: %ld\n", (long)GDK_WINDOW_XWINDOW(gui.mainwin->window)); + #endif fflush(stdout); } *************** *** 2416,2425 **** --- 2754,2770 ---- if (serverName == NULL && serverDelayedStartName != NULL) { /* This is a :gui command in a plain vim with no previous server */ + # if GTK_CHECK_VERSION(3,0,0) + commWindow = GDK_WINDOW_XID(mainwin_win); + + (void)serverRegisterName(GDK_WINDOW_XDISPLAY(mainwin_win), + serverDelayedStartName); + # else commWindow = GDK_WINDOW_XWINDOW(gui.mainwin->window); (void)serverRegisterName(GDK_WINDOW_XDISPLAY(gui.mainwin->window), serverDelayedStartName); + # endif } else { *************** *** 2428,2439 **** --- 2773,2794 ---- * have to change the "server" registration to that of the main window * If we have not registered a name yet, remember the window */ + # if GTK_CHECK_VERSION(3,0,0) + serverChangeRegisteredWindow(GDK_WINDOW_XDISPLAY(mainwin_win), + GDK_WINDOW_XID(mainwin_win)); + # else serverChangeRegisteredWindow(GDK_WINDOW_XDISPLAY(gui.mainwin->window), GDK_WINDOW_XWINDOW(gui.mainwin->window)); + # endif } gtk_widget_add_events(gui.mainwin, GDK_PROPERTY_CHANGE_MASK); + # if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.mainwin), "property-notify-event", + G_CALLBACK(property_event), NULL); + # else gtk_signal_connect(GTK_OBJECT(gui.mainwin), "property_notify_event", GTK_SIGNAL_FUNC(property_event), NULL); + # endif #endif } *************** *** 2441,2461 **** --- 2796,2855 ---- create_blank_pointer(void) { GdkWindow *root_window = NULL; + #if GTK_CHECK_VERSION(3,0,0) + GdkPixbuf *blank_mask; + #else GdkPixmap *blank_mask; + #endif GdkCursor *cursor; GdkColor color = { 0, 0, 0, 0 }; + #if !GTK_CHECK_VERSION(3,0,0) char blank_data[] = { 0x0 }; + #endif #ifdef HAVE_GTK_MULTIHEAD + # if GTK_CHECK_VERSION(3,12,0) + { + GdkWindow * const win = gtk_widget_get_window(gui.mainwin); + GdkScreen * const scrn = gdk_window_get_screen(win); + root_window = gdk_screen_get_root_window(scrn); + } + # else root_window = gtk_widget_get_root_window(gui.mainwin); + # endif #endif /* Create a pseudo blank pointer, which is in fact one pixel by one pixel * in size. */ + #if GTK_CHECK_VERSION(3,0,0) + { + cairo_surface_t *surf; + cairo_t *cr; + + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 1, 1); + cr = cairo_create(surf); + + cairo_set_source_rgb(cr, + color.red / 65535.0, + color.green / 65535.0, + color.blue / 65535.0); + cairo_rectangle(cr, 0, 0, 1, 1); + cairo_fill(cr); + cairo_destroy(cr); + + blank_mask = gdk_pixbuf_get_from_surface(surf, 0, 0, 1, 1); + cairo_surface_destroy(surf); + + cursor = gdk_cursor_new_from_pixbuf(gdk_window_get_display(root_window), + blank_mask, 0, 0); + g_object_unref(blank_mask); + } + #else blank_mask = gdk_bitmap_create_from_data(root_window, blank_data, 1, 1); cursor = gdk_cursor_new_from_pixmap(blank_mask, blank_mask, &color, &color, 0, 0); gdk_bitmap_unref(blank_mask); + #endif return cursor; } *************** *** 2473,2484 **** --- 2867,2888 ---- * Recreate the invisible mouse cursor. */ if (gui.blank_pointer != NULL) + # if GTK_CHECK_VERSION(3,0,0) + g_object_unref(G_OBJECT(gui.blank_pointer)); + # else gdk_cursor_unref(gui.blank_pointer); + # endif gui.blank_pointer = create_blank_pointer(); + # if GTK_CHECK_VERSION(3,0,0) + if (gui.pointer_hidden && gtk_widget_get_window(gui.drawarea) != NULL) + gdk_window_set_cursor(gtk_widget_get_window(gui.drawarea), + gui.blank_pointer); + # else if (gui.pointer_hidden && gui.drawarea->window != NULL) gdk_window_set_cursor(gui.drawarea->window, gui.blank_pointer); + # endif /* * Create a new PangoContext for this screen, and initialize it *************** *** 2509,2536 **** --- 2913,2966 ---- drawarea_realize_cb(GtkWidget *widget, gpointer data UNUSED) { GtkWidget *sbar; + #if GTK_CHECK_VERSION(3,0,0) + GtkAllocation allocation; + #endif #ifdef FEAT_XIM xim_init(); #endif gui_mch_new_colors(); + #if GTK_CHECK_VERSION(3,0,0) + gui.surface = gdk_window_create_similar_surface( + gtk_widget_get_window(widget), + CAIRO_CONTENT_COLOR_ALPHA, + gtk_widget_get_allocated_width(widget), + gtk_widget_get_allocated_height(widget)); + #else gui.text_gc = gdk_gc_new(gui.drawarea->window); + #endif gui.blank_pointer = create_blank_pointer(); if (gui.pointer_hidden) + #if GTK_CHECK_VERSION(3,0,0) + gdk_window_set_cursor(gtk_widget_get_window(widget), gui.blank_pointer); + #else gdk_window_set_cursor(widget->window, gui.blank_pointer); + #endif /* get the actual size of the scrollbars, if they are realized */ sbar = firstwin->w_scrollbars[SBAR_LEFT].id; if (!sbar || (!gui.which_scrollbars[SBAR_LEFT] && firstwin->w_scrollbars[SBAR_RIGHT].id)) sbar = firstwin->w_scrollbars[SBAR_RIGHT].id; + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_get_allocation(sbar, &allocation); + if (sbar && gtk_widget_get_realized(sbar) && allocation.width) + gui.scrollbar_width = allocation.width; + #else if (sbar && GTK_WIDGET_REALIZED(sbar) && sbar->allocation.width) gui.scrollbar_width = sbar->allocation.width; + #endif sbar = gui.bottom_sbar.id; + #if GTK_CHECK_VERSION(3,0,0) + if (sbar && gtk_widget_get_realized(sbar) && allocation.height) + gui.scrollbar_height = allocation.height; + #else if (sbar && GTK_WIDGET_REALIZED(sbar) && sbar->allocation.height) gui.scrollbar_height = sbar->allocation.height; + #endif } /* *************** *** 2558,2567 **** --- 2988,3009 ---- g_object_unref(gui.text_context); gui.text_context = NULL; + #if GTK_CHECK_VERSION(3,0,0) + if (gui.surface != NULL) + { + cairo_surface_destroy(gui.surface); + gui.surface = NULL; + } + #else g_object_unref(gui.text_gc); gui.text_gc = NULL; + #endif + #if GTK_CHECK_VERSION(3,0,0) + g_object_unref(G_OBJECT(gui.blank_pointer)); + #else gdk_cursor_unref(gui.blank_pointer); + #endif gui.blank_pointer = NULL; } *************** *** 2573,2578 **** --- 3015,3052 ---- gui_mch_new_colors(); } + #if GTK_CHECK_VERSION(3,0,0) + static gboolean + drawarea_configure_event_cb(GtkWidget *widget, + GdkEventConfigure *event, + gpointer data UNUSED) + { + static int cur_width = 0; + static int cur_height = 0; + + g_return_val_if_fail(event + && event->width >= 1 && event->height >= 1, TRUE); + + if (event->width == cur_width && event->height == cur_height) + return TRUE; + + cur_width = event->width; + cur_height = event->height; + + if (gui.surface != NULL) + cairo_surface_destroy(gui.surface); + + gui.surface = gdk_window_create_similar_surface( + gtk_widget_get_window(widget), + CAIRO_CONTENT_COLOR_ALPHA, + event->width, event->height); + + gtk_widget_queue_draw(widget); + + return TRUE; + } + #endif + /* * Callback routine for the "delete_event" signal on the toplevel window. * Tries to vim gracefully, or refuses to exit with changed buffers. *************** *** 2592,2598 **** { GtkOrientation item_orientation = GTK_ORIENTATION_HORIZONTAL; ! #ifdef FEAT_GUI_GNOME if (using_gnome && widget != NULL) { GtkWidget *parent; --- 3066,3072 ---- { GtkOrientation item_orientation = GTK_ORIENTATION_HORIZONTAL; ! # ifdef FEAT_GUI_GNOME if (using_gnome && widget != NULL) { GtkWidget *parent; *************** *** 2611,2626 **** item_orientation = bonobo_dock_item_get_orientation(dockitem); } } ! #endif if (widget != NULL && item_orientation == orientation && GTK_WIDGET_REALIZED(widget) && GTK_WIDGET_VISIBLE(widget)) { if (orientation == GTK_ORIENTATION_HORIZONTAL) return widget->allocation.height; else return widget->allocation.width; } return 0; } --- 3085,3118 ---- item_orientation = bonobo_dock_item_get_orientation(dockitem); } } ! # endif ! # if GTK_CHECK_VERSION(3,0,0) ! if (widget != NULL ! && item_orientation == orientation ! && gtk_widget_get_realized(widget) ! && gtk_widget_get_visible(widget)) ! # else if (widget != NULL && item_orientation == orientation && GTK_WIDGET_REALIZED(widget) && GTK_WIDGET_VISIBLE(widget)) + # endif { + # if GTK_CHECK_VERSION(3,0,0) + GtkAllocation allocation; + + gtk_widget_get_allocation(widget, &allocation); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + return allocation.height; + else + return allocation.width; + # else if (orientation == GTK_ORIENTATION_HORIZONTAL) return widget->allocation.height; else return widget->allocation.width; + # endif } return 0; } *************** *** 2774,2779 **** --- 3266,3282 ---- { GtkImage *image = (GtkImage *)widget; + # if GTK_CHECK_VERSION(3,10,0) + if (gtk_image_get_storage_type(image) == GTK_IMAGE_ICON_NAME) + { + const GtkIconSize icon_size = GPOINTER_TO_INT(user_data); + const gchar *icon_name; + + gtk_image_get_icon_name(image, &icon_name, NULL); + + gtk_image_set_from_icon_name(image, icon_name, icon_size); + } + # else /* User-defined icons are stored in a GtkIconSet */ if (gtk_image_get_storage_type(image) == GTK_IMAGE_ICON_SET) { *************** *** 2787,2792 **** --- 3290,3296 ---- gtk_image_set_from_icon_set(image, icon_set, icon_size); gtk_icon_set_unref(icon_set); } + # endif } else if (GTK_IS_CONTAINER(widget)) { *************** *** 2815,2821 **** --- 3319,3327 ---- style = GTK_TOOLBAR_ICONS; gtk_toolbar_set_style(toolbar, style); + # if !GTK_CHECK_VERSION(3,0,0) gtk_toolbar_set_tooltips(toolbar, (toolbar_flags & TOOLBAR_TOOLTIPS) != 0); + # endif switch (tbis_flags) { *************** *** 2847,2853 **** --- 3353,3361 ---- #if defined(FEAT_GUI_TABLINE) || defined(PROTO) static int ignore_tabline_evt = FALSE; static GtkWidget *tabline_menu; + # if !GTK_CHECK_VERSION(3,0,0) static GtkTooltips *tabline_tooltip; + # endif static int clicked_page; /* page clicked in tab line */ /* *************** *** 2872,2880 **** --- 3380,3394 ---- CONVERT_TO_UTF8_FREE(utf_text); gtk_container_add(GTK_CONTAINER(menu), item); + # if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(item), "activate", + G_CALLBACK(tabline_menu_handler), + GINT_TO_POINTER(resp)); + # else gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(tabline_menu_handler), (gpointer)(long)resp); + # endif } /* *************** *** 2916,2925 **** --- 3430,3449 ---- ) return TRUE; + # if GTK_CHECK_VERSION(3,0,0) + tabwin = gui_gtk_window_at_position(gui.mainwin, &x, &y); + # else tabwin = gdk_window_at_pointer(&x, &y); + # endif + gdk_window_get_user_data(tabwin, (gpointer)&tabwidget); + # if GTK_CHECK_VERSION(3,0,0) + clicked_page = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(tabwidget), + "tab_num")); + # else clicked_page = (int)(long)gtk_object_get_user_data( GTK_OBJECT(tabwidget)); + # endif /* If the event was generated for 3rd button popup the menu. */ if (bevent->button == 3) *************** *** 2950,2956 **** --- 3474,3484 ---- static void on_select_tab( GtkNotebook *notebook UNUSED, + # if GTK_CHECK_VERSION(3,0,0) + gpointer *page UNUSED, + # else GtkNotebookPage *page UNUSED, + # endif gint idx, gpointer data UNUSED) { *************** *** 2975,2981 **** --- 3503,3513 ---- gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), showit); update_window_manager_hints(0, 0); if (showit) + # if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_can_focus(GTK_WIDGET(gui.tabline), FALSE); + # else GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(gui.tabline), GTK_CAN_FOCUS); + # endif } gui_mch_update(); *************** *** 3023,3034 **** --- 3555,3573 ---- if (page == NULL) { /* Add notebook page */ + # if GTK_CHECK_VERSION(3,2,0) + page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_box_set_homogeneous(GTK_BOX(page), FALSE); + # else page = gtk_vbox_new(FALSE, 0); + # endif gtk_widget_show(page); event_box = gtk_event_box_new(); gtk_widget_show(event_box); label = gtk_label_new("-Empty-"); + # if !GTK_CHECK_VERSION(3,14,0) gtk_misc_set_padding(GTK_MISC(label), 2, 2); + # endif gtk_container_add(GTK_CONTAINER(event_box), label); gtk_widget_show(label); gtk_notebook_insert_page(GTK_NOTEBOOK(gui.tabline), *************** *** 3038,3046 **** --- 3577,3594 ---- } event_box = gtk_notebook_get_tab_label(GTK_NOTEBOOK(gui.tabline), page); + # if GTK_CHECK_VERSION(3,0,0) + g_object_set_data(G_OBJECT(event_box), "tab_num", + GINT_TO_POINTER(tab_num)); + # else gtk_object_set_user_data(GTK_OBJECT(event_box), (gpointer)(long)tab_num); + # endif + # if GTK_CHECK_VERSION(3,0,0) + label = gtk_bin_get_child(GTK_BIN(event_box)); + # else label = GTK_BIN(event_box)->child; + # endif get_tabline_label(tp, FALSE); labeltext = CONVERT_TO_UTF8(NameBuff); gtk_label_set_text(GTK_LABEL(label), (const char *)labeltext); *************** *** 3048,3055 **** --- 3596,3607 ---- get_tabline_label(tp, TRUE); labeltext = CONVERT_TO_UTF8(NameBuff); + # if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_tooltip_text(event_box, (const gchar *)labeltext); + # else gtk_tooltips_set_tip(GTK_TOOLTIPS(tabline_tooltip), event_box, (const char *)labeltext, NULL); + # endif CONVERT_TO_UTF8_FREE(labeltext); } *************** *** 3057,3064 **** --- 3609,3621 ---- while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(gui.tabline), nr) != NULL) gtk_notebook_remove_page(GTK_NOTEBOOK(gui.tabline), nr); + # if GTK_CHECK_VERSION(3,0,0) + if (gtk_notebook_get_current_page(GTK_NOTEBOOK(gui.tabline)) != curtabidx) + gtk_notebook_set_current_page(GTK_NOTEBOOK(gui.tabline), curtabidx); + # else if (gtk_notebook_current_page(GTK_NOTEBOOK(gui.tabline)) != curtabidx) gtk_notebook_set_page(GTK_NOTEBOOK(gui.tabline), curtabidx); + # endif /* Make sure everything is in place before drawing text. */ gui_mch_update(); *************** *** 3076,3083 **** --- 3633,3645 ---- return; ignore_tabline_evt = TRUE; + # if GTK_CHECK_VERSION(3,0,0) + if (gtk_notebook_get_current_page(GTK_NOTEBOOK(gui.tabline)) != nr - 1) + gtk_notebook_set_current_page(GTK_NOTEBOOK(gui.tabline), nr - 1); + # else if (gtk_notebook_current_page(GTK_NOTEBOOK(gui.tabline)) != nr - 1) gtk_notebook_set_page(GTK_NOTEBOOK(gui.tabline), nr - 1); + # endif ignore_tabline_evt = FALSE; } *************** *** 3187,3194 **** #endif /* FIXME: Need to install the classic icons and a gtkrc.classic file. * The hard part is deciding install locations and the Makefile magic. */ ! #if 0 gtk_rc_parse("gtkrc"); #endif /* Initialize values */ --- 3749,3758 ---- #endif /* FIXME: Need to install the classic icons and a gtkrc.classic file. * The hard part is deciding install locations and the Makefile magic. */ ! #if !GTK_CHECK_VERSION(3,0,0) ! # if 0 gtk_rc_parse("gtkrc"); + # endif #endif /* Initialize values */ *************** *** 3221,3227 **** --- 3785,3795 ---- #else plug = gtk_plug_new(gtk_socket_id); #endif + #if GTK_CHECK_VERSION(3,0,0) + if (plug != NULL && gtk_plug_get_socket_window(GTK_PLUG(plug)) != NULL) + #else if (plug != NULL && GTK_PLUG(plug)->socket_window != NULL) + #endif { gui.mainwin = plug; } *************** *** 3256,3269 **** --- 3824,3849 ---- gui.text_context = gtk_widget_create_pango_context(gui.mainwin); pango_context_set_base_dir(gui.text_context, PANGO_DIRECTION_LTR); + #if GTK_CHECK_VERSION(3,0,0) + gtk_container_set_border_width(GTK_CONTAINER(gui.mainwin), 0); + #else gtk_container_border_width(GTK_CONTAINER(gui.mainwin), 0); + #endif gtk_widget_add_events(gui.mainwin, GDK_VISIBILITY_NOTIFY_MASK); + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.mainwin), "delete-event", + G_CALLBACK(&delete_event_cb), NULL); + + g_signal_connect(G_OBJECT(gui.mainwin), "realize", + G_CALLBACK(&mainwin_realize), NULL); + #else gtk_signal_connect(GTK_OBJECT(gui.mainwin), "delete_event", GTK_SIGNAL_FUNC(&delete_event_cb), NULL); gtk_signal_connect(GTK_OBJECT(gui.mainwin), "realize", GTK_SIGNAL_FUNC(&mainwin_realize), NULL); + #endif #ifdef HAVE_GTK_MULTIHEAD g_signal_connect(G_OBJECT(gui.mainwin), "screen_changed", G_CALLBACK(&mainwin_screen_changed_cb), NULL); *************** *** 3272,3278 **** --- 3852,3863 ---- gtk_window_add_accel_group(GTK_WINDOW(gui.mainwin), gui.accel_group); /* A vertical box holds the menubar, toolbar and main text window. */ + #if GTK_CHECK_VERSION(3,2,0) + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE); + #else vbox = gtk_vbox_new(FALSE, 0); + #endif #ifdef FEAT_GUI_GNOME if (using_gnome) *************** *** 3335,3345 **** --- 3920,3936 ---- * Create the toolbar and handle */ /* some aesthetics on the toolbar */ + # ifdef USE_GTK3 + /* TODO: Add GTK+ 3 code here using GtkCssProvider if neccessary. */ + /* N.B. Since the default value of GtkToolbar::button-relief is + * GTK_RELIEF_NONE, there's no need to specify that, probably. */ + # else gtk_rc_parse_string( "style \"vim-toolbar-style\" {\n" " GtkToolbar::button_relief = GTK_RELIEF_NONE\n" "}\n" "widget \"*.vim-toolbar\" style \"vim-toolbar-style\"\n"); + # endif gui.toolbar = gtk_toolbar_new(); gtk_widget_set_name(gui.toolbar, "vim-toolbar"); set_toolbar_style(GTK_TOOLBAR(gui.toolbar)); *************** *** 3381,3422 **** gtk_notebook_set_show_border(GTK_NOTEBOOK(gui.tabline), FALSE); gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), FALSE); gtk_notebook_set_scrollable(GTK_NOTEBOOK(gui.tabline), TRUE); gtk_notebook_set_tab_border(GTK_NOTEBOOK(gui.tabline), FALSE); tabline_tooltip = gtk_tooltips_new(); gtk_tooltips_enable(GTK_TOOLTIPS(tabline_tooltip)); { GtkWidget *page, *label, *event_box; /* Add the first tab. */ page = gtk_vbox_new(FALSE, 0); gtk_widget_show(page); gtk_container_add(GTK_CONTAINER(gui.tabline), page); label = gtk_label_new("-Empty-"); gtk_widget_show(label); event_box = gtk_event_box_new(); gtk_widget_show(event_box); gtk_object_set_user_data(GTK_OBJECT(event_box), (gpointer)1L); gtk_misc_set_padding(GTK_MISC(label), 2, 2); gtk_container_add(GTK_CONTAINER(event_box), label); gtk_notebook_set_tab_label(GTK_NOTEBOOK(gui.tabline), page, event_box); } gtk_signal_connect(GTK_OBJECT(gui.tabline), "switch_page", GTK_SIGNAL_FUNC(on_select_tab), NULL); /* Create a popup menu for the tab line and connect it. */ tabline_menu = create_tabline_menu(); gtk_signal_connect_object(GTK_OBJECT(gui.tabline), "button_press_event", GTK_SIGNAL_FUNC(on_tabline_menu), GTK_OBJECT(tabline_menu)); ! #endif gui.formwin = gtk_form_new(); gtk_container_border_width(GTK_CONTAINER(gui.formwin), 0); gtk_widget_set_events(gui.formwin, GDK_EXPOSURE_MASK); gui.drawarea = gtk_drawing_area_new(); /* Determine which events we will filter. */ gtk_widget_set_events(gui.drawarea, --- 3972,4048 ---- gtk_notebook_set_show_border(GTK_NOTEBOOK(gui.tabline), FALSE); gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), FALSE); gtk_notebook_set_scrollable(GTK_NOTEBOOK(gui.tabline), TRUE); + # if !GTK_CHECK_VERSION(3,0,0) gtk_notebook_set_tab_border(GTK_NOTEBOOK(gui.tabline), FALSE); + # endif + # if !GTK_CHECK_VERSION(3,0,0) tabline_tooltip = gtk_tooltips_new(); gtk_tooltips_enable(GTK_TOOLTIPS(tabline_tooltip)); + # endif { GtkWidget *page, *label, *event_box; /* Add the first tab. */ + # if GTK_CHECK_VERSION(3,2,0) + page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_box_set_homogeneous(GTK_BOX(page), FALSE); + # else page = gtk_vbox_new(FALSE, 0); + # endif gtk_widget_show(page); gtk_container_add(GTK_CONTAINER(gui.tabline), page); label = gtk_label_new("-Empty-"); gtk_widget_show(label); event_box = gtk_event_box_new(); gtk_widget_show(event_box); + # if GTK_CHECK_VERSION(3,0,0) + g_object_set_data(G_OBJECT(event_box), "tab_num", GINT_TO_POINTER(1L)); + # else gtk_object_set_user_data(GTK_OBJECT(event_box), (gpointer)1L); + # endif + # if !GTK_CHECK_VERSION(3,14,0) gtk_misc_set_padding(GTK_MISC(label), 2, 2); + # endif gtk_container_add(GTK_CONTAINER(event_box), label); gtk_notebook_set_tab_label(GTK_NOTEBOOK(gui.tabline), page, event_box); } + # if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.tabline), "switch-page", + G_CALLBACK(on_select_tab), NULL); + # else gtk_signal_connect(GTK_OBJECT(gui.tabline), "switch_page", GTK_SIGNAL_FUNC(on_select_tab), NULL); + # endif /* Create a popup menu for the tab line and connect it. */ tabline_menu = create_tabline_menu(); + # if GTK_CHECK_VERSION(3,0,0) + g_signal_connect_swapped(G_OBJECT(gui.tabline), "button-press-event", + G_CALLBACK(on_tabline_menu), G_OBJECT(tabline_menu)); + # else gtk_signal_connect_object(GTK_OBJECT(gui.tabline), "button_press_event", GTK_SIGNAL_FUNC(on_tabline_menu), GTK_OBJECT(tabline_menu)); ! # endif ! #endif /* FEAT_GUI_TABLINE */ gui.formwin = gtk_form_new(); + #if GTK_CHECK_VERSION(3,0,0) + gtk_container_set_border_width(GTK_CONTAINER(gui.formwin), 0); + #else gtk_container_border_width(GTK_CONTAINER(gui.formwin), 0); + #endif + #if !GTK_CHECK_VERSION(3,0,0) gtk_widget_set_events(gui.formwin, GDK_EXPOSURE_MASK); + #endif gui.drawarea = gtk_drawing_area_new(); + #if GTK_CHECK_VERSION(3,0,0) + gui.surface = NULL; + gui.by_signal = FALSE; + #endif /* Determine which events we will filter. */ gtk_widget_set_events(gui.drawarea, *************** *** 3438,3455 **** /* For GtkSockets, key-presses must go to the focus widget (drawarea) * and not the window. */ gtk_signal_connect((gtk_socket_id == 0) ? GTK_OBJECT(gui.mainwin) : GTK_OBJECT(gui.drawarea), "key_press_event", GTK_SIGNAL_FUNC(key_press_event), NULL); ! #if defined(FEAT_XIM) /* Also forward key release events for the benefit of GTK+ 2 input * modules. Try CTRL-SHIFT-xdigits to enter a Unicode code point. */ g_signal_connect((gtk_socket_id == 0) ? G_OBJECT(gui.mainwin) : G_OBJECT(gui.drawarea), ! "key_release_event", G_CALLBACK(&key_release_event), NULL); #endif gtk_signal_connect(GTK_OBJECT(gui.drawarea), "realize", GTK_SIGNAL_FUNC(drawarea_realize_cb), NULL); gtk_signal_connect(GTK_OBJECT(gui.drawarea), "unrealize", --- 4064,4098 ---- /* For GtkSockets, key-presses must go to the focus widget (drawarea) * and not the window. */ + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect((gtk_socket_id == 0) ? G_OBJECT(gui.mainwin) + : G_OBJECT(gui.drawarea), + "key-press-event", + G_CALLBACK(key_press_event), NULL); + #else gtk_signal_connect((gtk_socket_id == 0) ? GTK_OBJECT(gui.mainwin) : GTK_OBJECT(gui.drawarea), "key_press_event", GTK_SIGNAL_FUNC(key_press_event), NULL); ! #endif ! #if defined(FEAT_XIM) || GTK_CHECK_VERSION(3,0,0) /* Also forward key release events for the benefit of GTK+ 2 input * modules. Try CTRL-SHIFT-xdigits to enter a Unicode code point. */ g_signal_connect((gtk_socket_id == 0) ? G_OBJECT(gui.mainwin) : G_OBJECT(gui.drawarea), ! "key-release-event", G_CALLBACK(&key_release_event), NULL); #endif + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.drawarea), "realize", + G_CALLBACK(drawarea_realize_cb), NULL); + g_signal_connect(G_OBJECT(gui.drawarea), "unrealize", + G_CALLBACK(drawarea_unrealize_cb), NULL); + g_signal_connect(G_OBJECT(gui.drawarea), "configure-event", + G_CALLBACK(drawarea_configure_event_cb), NULL); + g_signal_connect_after(G_OBJECT(gui.drawarea), "style-set", + G_CALLBACK(&drawarea_style_set_cb), NULL); + #else gtk_signal_connect(GTK_OBJECT(gui.drawarea), "realize", GTK_SIGNAL_FUNC(drawarea_realize_cb), NULL); gtk_signal_connect(GTK_OBJECT(gui.drawarea), "unrealize", *************** *** 3457,3464 **** --- 4100,4110 ---- gtk_signal_connect_after(GTK_OBJECT(gui.drawarea), "style_set", GTK_SIGNAL_FUNC(&drawarea_style_set_cb), NULL); + #endif + #if !GTK_CHECK_VERSION(3,0,0) gui.visibility = GDK_VISIBILITY_UNOBSCURED; + #endif #if !(defined(FEAT_GUI_GNOME) && defined(FEAT_SESSION)) wm_protocols_atom = gdk_atom_intern("WM_PROTOCOLS", FALSE); *************** *** 3467,3473 **** --- 4113,4123 ---- if (gtk_socket_id != 0) /* make sure keyboard input can go to the drawarea */ + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_can_focus(gui.drawarea, TRUE); + #else GTK_WIDGET_SET_FLAGS(gui.drawarea, GTK_CAN_FOCUS); + #endif /* * Set clipboard specific atoms *************** *** 3482,3491 **** --- 4132,4146 ---- */ gui.border_offset = gui.border_width; + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.drawarea), "draw", + G_CALLBACK(draw_event), NULL); + #else gtk_signal_connect(GTK_OBJECT(gui.mainwin), "visibility_notify_event", GTK_SIGNAL_FUNC(visibility_event), NULL); gtk_signal_connect(GTK_OBJECT(gui.drawarea), "expose_event", GTK_SIGNAL_FUNC(expose_event), NULL); + #endif /* * Only install these enter/leave callbacks when 'p' in 'guioptions'. *************** *** 3493,3502 **** --- 4148,4164 ---- */ if (vim_strchr(p_go, GO_POINTER) != NULL) { + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.drawarea), "leave-notify-event", + G_CALLBACK(leave_notify_event), NULL); + g_signal_connect(G_OBJECT(gui.drawarea), "enter-notify-event", + G_CALLBACK(enter_notify_event), NULL); + #else gtk_signal_connect(GTK_OBJECT(gui.drawarea), "leave_notify_event", GTK_SIGNAL_FUNC(leave_notify_event), NULL); gtk_signal_connect(GTK_OBJECT(gui.drawarea), "enter_notify_event", GTK_SIGNAL_FUNC(enter_notify_event), NULL); + #endif } /* Real windows can get focus ... GtkPlug, being a mere container can't, *************** *** 3505,3529 **** --- 4167,4222 ---- */ if (gtk_socket_id == 0) { + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.mainwin), "focus-out-event", + G_CALLBACK(focus_out_event), NULL); + g_signal_connect(G_OBJECT(gui.mainwin), "focus-in-event", + G_CALLBACK(focus_in_event), NULL); + #else gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_out_event", GTK_SIGNAL_FUNC(focus_out_event), NULL); gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_in_event", GTK_SIGNAL_FUNC(focus_in_event), NULL); + #endif } else { + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.drawarea), "focus-out-event", + G_CALLBACK(focus_out_event), NULL); + g_signal_connect(G_OBJECT(gui.drawarea), "focus-in-event", + G_CALLBACK(focus_in_event), NULL); + #else gtk_signal_connect(GTK_OBJECT(gui.drawarea), "focus_out_event", GTK_SIGNAL_FUNC(focus_out_event), NULL); gtk_signal_connect(GTK_OBJECT(gui.drawarea), "focus_in_event", GTK_SIGNAL_FUNC(focus_in_event), NULL); + #endif #ifdef FEAT_GUI_TABLINE + # if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.tabline), "focus-out-event", + G_CALLBACK(focus_out_event), NULL); + g_signal_connect(G_OBJECT(gui.tabline), "focus-in-event", + G_CALLBACK(focus_in_event), NULL); + # else gtk_signal_connect(GTK_OBJECT(gui.tabline), "focus_out_event", GTK_SIGNAL_FUNC(focus_out_event), NULL); gtk_signal_connect(GTK_OBJECT(gui.tabline), "focus_in_event", GTK_SIGNAL_FUNC(focus_in_event), NULL); + # endif #endif /* FEAT_GUI_TABLINE */ } + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.drawarea), "motion-notify-event", + G_CALLBACK(motion_notify_event), NULL); + g_signal_connect(G_OBJECT(gui.drawarea), "button-press-event", + G_CALLBACK(button_press_event), NULL); + g_signal_connect(G_OBJECT(gui.drawarea), "button-release-event", + G_CALLBACK(button_release_event), NULL); + g_signal_connect(G_OBJECT(gui.drawarea), "scroll-event", + G_CALLBACK(&scroll_event), NULL); + #else gtk_signal_connect(GTK_OBJECT(gui.drawarea), "motion_notify_event", GTK_SIGNAL_FUNC(motion_notify_event), NULL); gtk_signal_connect(GTK_OBJECT(gui.drawarea), "button_press_event", *************** *** 3532,3550 **** --- 4225,4256 ---- GTK_SIGNAL_FUNC(button_release_event), NULL); g_signal_connect(G_OBJECT(gui.drawarea), "scroll_event", G_CALLBACK(&scroll_event), NULL); + #endif /* * Add selection handler functions. */ + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.drawarea), "selection-clear-event", + G_CALLBACK(selection_clear_event), NULL); + g_signal_connect(G_OBJECT(gui.drawarea), "selection-received", + G_CALLBACK(selection_received_cb), NULL); + #else gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_clear_event", GTK_SIGNAL_FUNC(selection_clear_event), NULL); gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_received", GTK_SIGNAL_FUNC(selection_received_cb), NULL); + #endif gui_gtk_set_selection_targets(); + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.drawarea), "selection-get", + G_CALLBACK(selection_get_cb), NULL); + #else gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_get", GTK_SIGNAL_FUNC(selection_get_cb), NULL); + #endif /* Pretend we don't have input focus, we will get an event if we do. */ gui.in_focus = FALSE; *************** *** 3572,3577 **** --- 4278,4344 ---- } #endif /* FEAT_GUI_GNOME && FEAT_SESSION */ + #if GTK_CHECK_VERSION(3,0,0) + static void + gui_gtk_get_rgb_from_pixel(guint32 pixel, GdkRGBA *result) + { + GdkVisual * const visual = gtk_widget_get_visual(gui.drawarea); + guint32 r_mask, g_mask, b_mask; + gint r_shift, g_shift, b_shift; + + if (visual == NULL) + { + result->red = 0.0; + result->green = 0.0; + result->blue = 0.0; + result->alpha = 0.0; + return; + } + + 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); + + result->red = ((pixel & r_mask) >> r_shift) / 255.0; + result->green = ((pixel & g_mask) >> g_shift) / 255.0; + result->blue = ((pixel & b_mask) >> b_shift) / 255.0; + result->alpha = 1.0; + } + + /* Convert a GdRGBA into a pixel value using drawarea's visual */ + static guint32 + gui_gtk_get_pixel_from_rgb(const GdkRGBA *rgba) + { + GdkVisual * const visual = gtk_widget_get_visual(gui.drawarea); + guint32 r_mask, g_mask, b_mask; + gint r_shift, g_shift, b_shift; + guint32 r, g, b; + + if (visual == NULL) + return 0; + + 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); + + r = rgba->red * 65535; + g = rgba->green * 65535; + b = rgba->blue * 65535; + + return ((r << r_shift) & r_mask) | + ((g << g_shift) & g_mask) | + ((b << b_shift) & b_mask); + } + + static void + set_cairo_source_rgb_from_pixel(cairo_t *cr, guint32 pixel) + { + GdkRGBA result; + gui_gtk_get_rgb_from_pixel(pixel, &result); + cairo_set_source_rgb(cr, result.red, result.green, result.blue); + } + #endif /* GTK_CHECK_VERSION(3,0,0) */ + /* * Called when the foreground or background color has been changed. * This used to change the graphics contexts directly but we are *************** *** 3580,3591 **** --- 4347,4385 ---- void gui_mch_new_colors(void) { + #if GTK_CHECK_VERSION(3,0,0) + GdkWindow * const da_win = gtk_widget_get_window(gui.drawarea); + + if (gui.drawarea != NULL && gtk_widget_get_window(gui.drawarea) != NULL) + #else if (gui.drawarea != NULL && gui.drawarea->window != NULL) + #endif { + #if GTK_CHECK_VERSION(3,4,0) + GdkRGBA color; + + gui_gtk_get_rgb_from_pixel(gui.back_pixel, &color); + { + cairo_pattern_t * const pat = cairo_pattern_create_rgba( + color.red, color.green, color.blue, color.alpha); + if (pat != NULL) + { + gdk_window_set_background_pattern(da_win, pat); + cairo_pattern_destroy(pat); + } + else + gdk_window_set_background_rgba(da_win, &color); + } + #else /* !GTK_CHECK_VERSION(3,4,0) */ GdkColor color = { 0, 0, 0, 0 }; color.pixel = gui.back_pixel; + # if GTK_CHECK_VERSION(3,0,0) + gdk_window_set_background(da_win, &color); + # else gdk_window_set_background(gui.drawarea->window, &color); + # endif + #endif /* !GTK_CHECK_VERSION(3,4,0) */ } } *************** *** 3618,3625 **** --- 4412,4424 ---- * We can't do much more here than to trying to preserve what had been done, * since the window is already inevitably going away. */ + #if GTK_CHECK_VERSION(3,0,0) + static void + mainwin_destroy_cb(GObject *object UNUSED, gpointer data UNUSED) + #else static void mainwin_destroy_cb(GtkObject *object UNUSED, gpointer data UNUSED) + #endif { /* Don't write messages to the GUI anymore */ full_screen = FALSE; *************** *** 3799,3806 **** --- 4598,4610 ---- * changed them). */ highlight_gui_started(); /* re-init colors and fonts */ + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.mainwin), "destroy", + G_CALLBACK(mainwin_destroy_cb), NULL); + #else gtk_signal_connect(GTK_OBJECT(gui.mainwin), "destroy", GTK_SIGNAL_FUNC(mainwin_destroy_cb), NULL); + #endif #ifdef FEAT_HANGULIN hangul_keyboard_set(); *************** *** 3816,3830 **** --- 4620,4644 ---- * manager upon us and should not interfere with what VIM is requesting * upon startup. */ + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.formwin), "configure-event", + G_CALLBACK(form_configure_event), NULL); + #else gtk_signal_connect(GTK_OBJECT(gui.formwin), "configure_event", GTK_SIGNAL_FUNC(form_configure_event), NULL); + #endif #ifdef FEAT_DND /* Set up for receiving DND items. */ gui_gtk_set_dnd_targets(); + # if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(gui.drawarea), "drag-data-received", + G_CALLBACK(drag_data_received_cb), NULL); + # else gtk_signal_connect(GTK_OBJECT(gui.drawarea), "drag_data_received", GTK_SIGNAL_FUNC(drag_data_received_cb), NULL); + # endif #endif /* With GTK+ 2, we need to iconify the window before calling show() *************** *** 3901,3907 **** gtk_window_move(GTK_WINDOW(gui.mainwin), x, y); } ! #if 0 static int resize_idle_installed = FALSE; /* * Idle handler to force resize. Used by gui_mch_set_shellsize() to ensure --- 4715,4722 ---- gtk_window_move(GTK_WINDOW(gui.mainwin), x, y); } ! #if !GTK_CHECK_VERSION(3,0,0) ! # if 0 static int resize_idle_installed = FALSE; /* * Idle handler to force resize. Used by gui_mch_set_shellsize() to ensure *************** *** 3937,3943 **** resize_idle_installed = FALSE; return FALSE; /* don't call me again */ } ! #endif /* * Return TRUE if the main window is maximized. --- 4752,4759 ---- resize_idle_installed = FALSE; return FALSE; /* don't call me again */ } ! # endif ! #endif /* !GTK_CHECK_VERSION(3,0,0) */ /* * Return TRUE if the main window is maximized. *************** *** 3945,3953 **** --- 4761,4775 ---- int gui_mch_maximized(void) { + #if GTK_CHECK_VERSION(3,0,0) + return (gui.mainwin != NULL && gtk_widget_get_window(gui.mainwin) != NULL + && (gdk_window_get_state(gtk_widget_get_window(gui.mainwin)) + & GDK_WINDOW_STATE_MAXIMIZED)); + #else return (gui.mainwin != NULL && gui.mainwin->window != NULL && (gdk_window_get_state(gui.mainwin->window) & GDK_WINDOW_STATE_MAXIMIZED)); + #endif } /* *************** *** 4002,4015 **** else update_window_manager_hints(width, height); ! # if 0 if (!resize_idle_installed) { g_idle_add_full(GDK_PRIORITY_EVENTS + 10, &force_shell_resize_idle, NULL, NULL); resize_idle_installed = TRUE; } ! # endif /* * Wait until all events are processed to prevent a crash because the * real size of the drawing area doesn't reflect Vim's internal ideas. --- 4824,4839 ---- else update_window_manager_hints(width, height); ! # if !GTK_CHECK_VERSION(3,0,0) ! # if 0 if (!resize_idle_installed) { g_idle_add_full(GDK_PRIORITY_EVENTS + 10, &force_shell_resize_idle, NULL, NULL); resize_idle_installed = TRUE; } ! # endif ! # endif /* !GTK_CHECK_VERSION(3,0,0) */ /* * Wait until all events are processed to prevent a crash because the * real size of the drawing area doesn't reflect Vim's internal ideas. *************** *** 4084,4090 **** --- 4908,4918 ---- widget = gui.menubar; /* Do not disable the menu while starting up, otherwise F10 doesn't work. */ + # if GTK_CHECK_VERSION(3,0,0) + if (!showit != !gtk_widget_get_visible(widget) && !gui.starting) + # else if (!showit != !GTK_WIDGET_VISIBLE(widget) && !gui.starting) + # endif { if (showit) gtk_widget_show(widget); *************** *** 4115,4121 **** --- 4943,4953 ---- if (showit) set_toolbar_style(GTK_TOOLBAR(gui.toolbar)); + # if GTK_CHECK_VERSION(3,0,0) + if (!showit != !gtk_widget_get_visible(widget)) + # else if (!showit != !GTK_WIDGET_VISIBLE(widget)) + # endif { if (showit) gtk_widget_show(widget); *************** *** 4200,4205 **** --- 5032,5048 ---- return OK; } + #if GTK_CHECK_VERSION(3,0,0) + /* Callback function used in gui_mch_font_dialog() */ + static gboolean + font_filter(const PangoFontFamily *family, + const PangoFontFace *face UNUSED, + gpointer data UNUSED) + { + return pango_font_family_is_monospace((PangoFontFamily *)family); + } + #endif + /* * Put up a font dialog and return the selected font name in allocated memory. * "oldval" is the previous value. Return NULL when cancelled. *************** *** 4217,4223 **** --- 5060,5072 ---- char_u *fontname = NULL; char_u *oldname; + #if GTK_CHECK_VERSION(3,2,0) + dialog = gtk_font_chooser_dialog_new(NULL, NULL); + gtk_font_chooser_set_filter_func(GTK_FONT_CHOOSER(dialog), font_filter, + NULL, NULL); + #else dialog = gtk_font_selection_dialog_new(NULL); + #endif gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(gui.mainwin)); gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); *************** *** 4244,4258 **** --- 5093,5117 ---- } } + #if GTK_CHECK_VERSION(3,2,0) + gtk_font_chooser_set_font( + GTK_FONT_CHOOSER(dialog), (const gchar *)oldname); + #else gtk_font_selection_dialog_set_font_name( GTK_FONT_SELECTION_DIALOG(dialog), (const char *)oldname); + #endif if (oldname != oldval) vim_free(oldname); } else + #if GTK_CHECK_VERSION(3,2,0) + gtk_font_chooser_set_font( + GTK_FONT_CHOOSER(dialog), DEFAULT_FONT); + #else gtk_font_selection_dialog_set_font_name( GTK_FONT_SELECTION_DIALOG(dialog), DEFAULT_FONT); + #endif response = gtk_dialog_run(GTK_DIALOG(dialog)); *************** *** 4260,4267 **** --- 5119,5130 ---- { char *name; + #if GTK_CHECK_VERSION(3,2,0) + name = gtk_font_chooser_get_font(GTK_FONT_CHOOSER(dialog)); + #else name = gtk_font_selection_dialog_get_font_name( GTK_FONT_SELECTION_DIALOG(dialog)); + #endif if (name != NULL) { char_u *p; *************** *** 4636,4652 **** --- 5499,5527 ---- while (name != NULL) { + #if GTK_CHECK_VERSION(3,0,0) + GdkRGBA color; + #else GdkColor color; + #endif int parsed; int i; + #if GTK_CHECK_VERSION(3,0,0) + parsed = gdk_rgba_parse(&color, (const gchar *)name); + #else parsed = gdk_color_parse((const char *)name, &color); + #endif if (parsed) { + #if GTK_CHECK_VERSION(3,0,0) + return (guicolor_T)gui_gtk_get_pixel_from_rgb(&color); + #else gdk_colormap_alloc_color(gtk_widget_get_colormap(gui.drawarea), &color, FALSE, TRUE); return (guicolor_T)color.pixel; + #endif } /* add a few builtin names and try again */ for (i = 0; ; ++i) *************** *** 4838,4849 **** --- 5713,5738 ---- glyph->geometry.x_offset = -width + MAX(0, width - ink_rect.width) / 2; } + #if GTK_CHECK_VERSION(3,0,0) + static void + draw_glyph_string(int row, int col, int num_cells, int flags, + PangoFont *font, PangoGlyphString *glyphs, + cairo_t *cr) + #else static void draw_glyph_string(int row, int col, int num_cells, int flags, PangoFont *font, PangoGlyphString *glyphs) + #endif { if (!(flags & DRAW_TRANSP)) { + #if GTK_CHECK_VERSION(3,0,0) + set_cairo_source_rgb_from_pixel(cr, gui.bgcolor->pixel); + cairo_rectangle(cr, + FILL_X(col), FILL_Y(row), + num_cells * gui.char_width, gui.char_height); + cairo_fill(cr); + #else gdk_gc_set_foreground(gui.text_gc, gui.bgcolor); gdk_draw_rectangle(gui.drawarea->window, *************** *** 4853,4860 **** --- 5742,5755 ---- FILL_Y(row), num_cells * gui.char_width, gui.char_height); + #endif } + #if GTK_CHECK_VERSION(3,0,0) + set_cairo_source_rgb_from_pixel(cr, gui.fgcolor->pixel); + cairo_move_to(cr, TEXT_X(col), TEXT_Y(row)); + pango_cairo_show_glyph_string(cr, font, glyphs); + #else gdk_gc_set_foreground(gui.text_gc, gui.fgcolor); gdk_draw_glyphs(gui.drawarea->window, *************** *** 4863,4884 **** --- 5758,5793 ---- TEXT_X(col), TEXT_Y(row), glyphs); + #endif /* redraw the contents with an offset of 1 to emulate bold */ if ((flags & DRAW_BOLD) && !gui.font_can_bold) + #if GTK_CHECK_VERSION(3,0,0) + { + set_cairo_source_rgb_from_pixel(cr, gui.fgcolor->pixel); + cairo_move_to(cr, TEXT_X(col) + 1, TEXT_Y(row)); + pango_cairo_show_glyph_string(cr, font, glyphs); + } + #else gdk_draw_glyphs(gui.drawarea->window, gui.text_gc, font, TEXT_X(col) + 1, TEXT_Y(row), glyphs); + #endif } /* * Draw underline and undercurl at the bottom of the character cell. */ + #if GTK_CHECK_VERSION(3,0,0) + static void + draw_under(int flags, int row, int col, int cells, cairo_t *cr) + #else static void draw_under(int flags, int row, int col, int cells) + #endif { int i; int offset; *************** *** 4888,4893 **** --- 5797,5813 ---- /* Undercurl: draw curl at the bottom of the character cell. */ if (flags & DRAW_UNDERC) { + #if GTK_CHECK_VERSION(3,0,0) + cairo_set_line_width(cr, 1.0); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT); + set_cairo_source_rgb_from_pixel(cr, gui.spcolor->pixel); + for (i = FILL_X(col); i < FILL_X(col + cells); ++i) + { + offset = val[i % 8]; + cairo_line_to(cr, i, y - offset + 0.5); + } + cairo_stroke(cr); + #else gdk_gc_set_foreground(gui.text_gc, gui.spcolor); for (i = FILL_X(col); i < FILL_X(col + cells); ++i) { *************** *** 4895,4900 **** --- 5815,5821 ---- gdk_draw_point(gui.drawarea->window, gui.text_gc, i, y - offset); } gdk_gc_set_foreground(gui.text_gc, gui.fgcolor); + #endif } /* Underline: draw a line at the bottom of the character cell. */ *************** *** 4904,4912 **** --- 5825,5844 ---- * Otherwise put the line just below the character. */ if (p_linespace > 1) y -= p_linespace - 1; + #if GTK_CHECK_VERSION(3,0,0) + { + cairo_set_line_width(cr, 1.0); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT); + set_cairo_source_rgb_from_pixel(cr, gui.fgcolor->pixel); + cairo_move_to(cr, FILL_X(col), y + 0.5); + cairo_line_to(cr, FILL_X(col + cells), y + 0.5); + cairo_stroke(cr); + } + #else gdk_draw_line(gui.drawarea->window, gui.text_gc, FILL_X(col), y, FILL_X(col + cells) - 1, y); + #endif } } *************** *** 4922,4929 **** --- 5854,5868 ---- int convlen; char_u *sp, *bp; int plen; + #if GTK_CHECK_VERSION(3,0,0) + cairo_t *cr; + #endif + #if GTK_CHECK_VERSION(3,0,0) + if (gui.text_context == NULL || gtk_widget_get_window(gui.drawarea) == NULL) + #else if (gui.text_context == NULL || gui.drawarea->window == NULL) + #endif return len; if (output_conv.vc_type != CONV_NONE) *************** *** 4976,4983 **** --- 5915,5928 ---- area.width = gui.num_cols * gui.char_width; area.height = gui.char_height; + #if GTK_CHECK_VERSION(3,0,0) + cr = cairo_create(gui.surface); + cairo_rectangle(cr, area.x, area.y, area.width, area.height); + cairo_clip(cr); + #else gdk_gc_set_clip_origin(gui.text_gc, 0, 0); gdk_gc_set_clip_rectangle(gui.text_gc, &area); + #endif glyphs = pango_glyph_string_new(); *************** *** 5004,5010 **** --- 5949,5959 ---- glyphs->log_clusters[i] = i; } + #if GTK_CHECK_VERSION(3,0,0) + draw_glyph_string(row, col, len, flags, gui.ascii_font, glyphs, cr); + #else draw_glyph_string(row, col, len, flags, gui.ascii_font, glyphs); + #endif column_offset = len; } *************** *** 5162,5169 **** --- 6111,6124 ---- } /*** Aaaaand action! ***/ + #if GTK_CHECK_VERSION(3,0,0) + draw_glyph_string(row, col + column_offset, item_cells, + flags, item->analysis.font, glyphs, + cr); + #else draw_glyph_string(row, col + column_offset, item_cells, flags, item->analysis.font, glyphs); + #endif pango_item_free(item); *************** *** 5175,5186 **** --- 6130,6152 ---- skipitall: /* Draw underline and undercurl. */ + #if GTK_CHECK_VERSION(3,0,0) + draw_under(flags, row, col, column_offset, cr); + #else draw_under(flags, row, col, column_offset); + #endif pango_glyph_string_free(glyphs); vim_free(conv_buf); + #if GTK_CHECK_VERSION(3,0,0) + cairo_destroy(cr); + if (!gui.by_signal) + gdk_window_invalidate_rect(gtk_widget_get_window(gui.drawarea), + &area, FALSE); + #else gdk_gc_set_clip_rectangle(gui.text_gc, NULL); + #endif return column_offset; } *************** *** 5207,5216 **** --- 6173,6191 ---- int gui_get_x11_windis(Window *win, Display **dis) { + #if GTK_CHECK_VERSION(3,0,0) + if (gui.mainwin != NULL && gtk_widget_get_window(gui.mainwin) != NULL) + #else if (gui.mainwin != NULL && gui.mainwin->window != NULL) + #endif { + #if GTK_CHECK_VERSION(3,0,0) + *dis = GDK_WINDOW_XDISPLAY(gtk_widget_get_window(gui.mainwin)); + *win = GDK_WINDOW_XID(gtk_widget_get_window(gui.mainwin)); + #else *dis = GDK_WINDOW_XDISPLAY(gui.mainwin->window); *win = GDK_WINDOW_XWINDOW(gui.mainwin->window); + #endif return OK; } *************** *** 5226,5233 **** --- 6201,6213 ---- Display * gui_mch_get_display(void) { + #if GTK_CHECK_VERSION(3,0,0) + if (gui.mainwin != NULL && gtk_widget_get_window(gui.mainwin) != NULL) + return GDK_WINDOW_XDISPLAY(gtk_widget_get_window(gui.mainwin)); + #else if (gui.mainwin != NULL && gui.mainwin->window != NULL) return GDK_WINDOW_XDISPLAY(gui.mainwin->window); + #endif else return NULL; } *************** *** 5239,5245 **** --- 6219,6229 ---- #ifdef HAVE_GTK_MULTIHEAD GdkDisplay *display; + # if GTK_CHECK_VERSION(3,0,0) + if (gui.mainwin != NULL && gtk_widget_get_realized(gui.mainwin)) + # else if (gui.mainwin != NULL && GTK_WIDGET_REALIZED(gui.mainwin)) + # endif display = gtk_widget_get_display(gui.mainwin); else display = gdk_display_get_default(); *************** *** 5254,5259 **** --- 6238,6247 ---- void gui_mch_flash(int msec) { + #if GTK_CHECK_VERSION(3,0,0) + /* TODO Replace GdkGC with Cairo */ + (void)msec; + #else GdkGCValues values; GdkGC *invert_gc; *************** *** 5293,5298 **** --- 6281,6287 ---- FILL_Y((int)Rows) + gui.border_offset); gdk_gc_destroy(invert_gc); + #endif } /* *************** *** 5301,5306 **** --- 6290,6299 ---- void gui_mch_invert_rectangle(int r, int c, int nr, int nc) { + #if GTK_CHECK_VERSION(3,0,0) + /* TODO Replace GdkGC with Cairo */ + (void)r; (void)c; (void)nr; (void)nc; + #else GdkGCValues values; GdkGC *invert_gc; *************** *** 5322,5327 **** --- 6315,6321 ---- FILL_X(c), FILL_Y(r), (nc) * gui.char_width, (nr) * gui.char_height); gdk_gc_destroy(invert_gc); + #endif } /* *************** *** 5351,5369 **** --- 6345,6388 ---- gui_mch_draw_hollow_cursor(guicolor_T color) { int i = 1; + #if GTK_CHECK_VERSION(3,0,0) + cairo_t *cr; + #endif + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_window(gui.drawarea) == NULL) + #else if (gui.drawarea->window == NULL) + #endif return; + #if GTK_CHECK_VERSION(3,0,0) + cr = cairo_create(gui.surface); + #endif + gui_mch_set_fg_color(color); + #if GTK_CHECK_VERSION(3,0,0) + set_cairo_source_rgb_from_pixel(cr, gui.fgcolor->pixel); + #else gdk_gc_set_foreground(gui.text_gc, gui.fgcolor); + #endif if (mb_lefthalve(gui.row, gui.col)) i = 2; + #if GTK_CHECK_VERSION(3,0,0) + cairo_set_line_width(cr, 1.0); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT); + cairo_rectangle(cr, + FILL_X(gui.col) + 0.5, FILL_Y(gui.row) + 0.5, + i * gui.char_width - 1, gui.char_height - 1); + cairo_stroke(cr); + cairo_destroy(cr); + #else gdk_draw_rectangle(gui.drawarea->window, gui.text_gc, FALSE, FILL_X(gui.col), FILL_Y(gui.row), i * gui.char_width - 1, gui.char_height - 1); + #endif } /* *************** *** 5373,5393 **** void gui_mch_draw_part_cursor(int w, int h, guicolor_T color) { if (gui.drawarea->window == NULL) return; gui_mch_set_fg_color(color); gdk_gc_set_foreground(gui.text_gc, gui.fgcolor); gdk_draw_rectangle(gui.drawarea->window, gui.text_gc, TRUE, ! #ifdef FEAT_RIGHTLEFT /* vertical line should be on the right of current point */ CURSOR_BAR_RIGHT ? FILL_X(gui.col + 1) - w : ! #endif FILL_X(gui.col), FILL_Y(gui.row) + gui.char_height - h, w, h); } --- 6392,6434 ---- void gui_mch_draw_part_cursor(int w, int h, guicolor_T color) { + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_window(gui.drawarea) == NULL) + #else if (gui.drawarea->window == NULL) + #endif return; gui_mch_set_fg_color(color); + #if GTK_CHECK_VERSION(3,0,0) + { + cairo_t *cr; + + cr = cairo_create(gui.surface); + set_cairo_source_rgb_from_pixel(cr, gui.fgcolor->pixel); + cairo_rectangle(cr, + # ifdef FEAT_RIGHTLEFT + /* vertical line should be on the right of current point */ + CURSOR_BAR_RIGHT ? FILL_X(gui.col + 1) - w : + # endif + FILL_X(gui.col), FILL_Y(gui.row) + gui.char_height - h, + w, h); + cairo_fill(cr); + cairo_destroy(cr); + } + #else /* !GTK_CHECK_VERSION(3,0,0) */ gdk_gc_set_foreground(gui.text_gc, gui.fgcolor); gdk_draw_rectangle(gui.drawarea->window, gui.text_gc, TRUE, ! # ifdef FEAT_RIGHTLEFT /* vertical line should be on the right of current point */ CURSOR_BAR_RIGHT ? FILL_X(gui.col + 1) - w : ! # endif FILL_X(gui.col), FILL_Y(gui.row) + gui.char_height - h, w, h); + #endif /* !GTK_CHECK_VERSION(3,0,0) */ } *************** *** 5404,5410 **** --- 6445,6455 ---- g_main_context_iteration(NULL, TRUE); } + #if GTK_CHECK_VERSION(3,0,0) + static gboolean + #else static gint + #endif input_timer_cb(gpointer data) { int *timed_out = (int *) data; *************** *** 5473,5479 **** --- 6518,6528 ---- * time */ if (wtime > 0) + #if GTK_CHECK_VERSION(3,0,0) + timer = g_timeout_add((guint)wtime, input_timer_cb, &timed_out); + #else timer = gtk_timeout_add((guint32)wtime, input_timer_cb, &timed_out); + #endif else timer = 0; *************** *** 5507,5513 **** --- 6556,6566 ---- if (input_available()) { if (timer != 0 && !timed_out) + #if GTK_CHECK_VERSION(3,0,0) + g_source_remove(timer); + #else gtk_timeout_remove(timer); + #endif return OK; } } while (wtime < 0 || !timed_out); *************** *** 5531,5545 **** --- 6584,6607 ---- gui_mch_flush(void) { #ifdef HAVE_GTK_MULTIHEAD + # if GTK_CHECK_VERSION(3,0,0) + if (gui.mainwin != NULL && gtk_widget_get_realized(gui.mainwin)) + # else if (gui.mainwin != NULL && GTK_WIDGET_REALIZED(gui.mainwin)) + # endif gdk_display_sync(gtk_widget_get_display(gui.mainwin)); #else gdk_flush(); /* historical misnomer: calls XSync(), not XFlush() */ #endif /* This happens to actually do what gui_mch_flush() is supposed to do, * according to the comment above. */ + #if GTK_CHECK_VERSION(3,0,0) + if (gui.drawarea != NULL && gtk_widget_get_window(gui.drawarea) != NULL) + gdk_window_process_updates(gtk_widget_get_window(gui.drawarea), FALSE); + #else if (gui.drawarea != NULL && gui.drawarea->window != NULL) gdk_window_process_updates(gui.drawarea->window, FALSE); + #endif } /* *************** *** 5549,5561 **** --- 6611,6652 ---- void gui_mch_clear_block(int row1, int col1, int row2, int col2) { + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_window(gui.drawarea) == NULL) + return; + #else GdkColor color; if (gui.drawarea->window == NULL) return; color.pixel = gui.back_pixel; + #endif + #if GTK_CHECK_VERSION(3,0,0) + { + /* Add one pixel to the far right column in case a double-stroked + * bold glyph may sit there. */ + const GdkRectangle rect = { + FILL_X(col1), FILL_Y(row1), + (col2 - col1 + 1) * gui.char_width + (col2 == Columns - 1), + (row2 - row1 + 1) * gui.char_height + }; + GdkWindow * const win = gtk_widget_get_window(gui.drawarea); + cairo_t * const cr = cairo_create(gui.surface); + cairo_pattern_t * const pat = gdk_window_get_background_pattern(win); + if (pat != NULL) + cairo_set_source(cr, pat); + else + set_cairo_source_rgb_from_pixel(cr, gui.back_pixel); + gdk_cairo_rectangle(cr, &rect); + cairo_fill(cr); + cairo_destroy(cr); + + if (!gui.by_signal) + gdk_window_invalidate_rect(win, &rect, FALSE); + } + #else /* !GTK_CHECK_VERSION(3,0,0) */ gdk_gc_set_foreground(gui.text_gc, &color); /* Clear one extra pixel at the far right, for when bold characters have *************** *** 5565,5579 **** --- 6656,6699 ---- (col2 - col1 + 1) * gui.char_width + (col2 == Columns - 1), (row2 - row1 + 1) * gui.char_height); + #endif /* !GTK_CHECK_VERSION(3,0,0) */ } + #if GTK_CHECK_VERSION(3,0,0) + static void + gui_gtk_window_clear(GdkWindow *win) + { + const GdkRectangle rect = { + 0, 0, gdk_window_get_width(win), gdk_window_get_height(win) + }; + cairo_t * const cr = cairo_create(gui.surface); + cairo_pattern_t * const pat = gdk_window_get_background_pattern(win); + if (pat != NULL) + cairo_set_source(cr, pat); + else + set_cairo_source_rgb_from_pixel(cr, gui.back_pixel); + gdk_cairo_rectangle(cr, &rect); + cairo_fill(cr); + cairo_destroy(cr); + + if (!gui.by_signal) + gdk_window_invalidate_rect(win, &rect, FALSE); + } + #endif + void gui_mch_clear_all(void) { + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_window(gui.drawarea) != NULL) + gui_gtk_window_clear(gtk_widget_get_window(gui.drawarea)); + #else if (gui.drawarea->window != NULL) gdk_window_clear(gui.drawarea->window); + #endif } + #if !GTK_CHECK_VERSION(3,0,0) /* * Redraw any text revealed by scrolling up/down. */ *************** *** 5610,5615 **** --- 6730,6756 ---- gui_can_update_cursor(); } + #endif /* !GTK_CHECK_VERSION(3,0,0) */ + + #if GTK_CHECK_VERSION(3,0,0) + static void + gui_gtk_surface_copy_rect(int dest_x, int dest_y, + int src_x, int src_y, + int width, int height) + { + cairo_t * const cr = cairo_create(gui.surface); + + cairo_rectangle(cr, dest_x, dest_y, width, height); + cairo_clip(cr); + cairo_push_group(cr); + cairo_set_source_surface(cr, gui.surface, dest_x - src_x, dest_y - src_y); + cairo_paint(cr); + cairo_pop_group_to_source(cr); + cairo_paint(cr); + + cairo_destroy(cr); + } + #endif /* * Delete the given number of lines from the given row, scrolling up any *************** *** 5618,5623 **** --- 6759,6784 ---- void gui_mch_delete_lines(int row, int num_lines) { + #if GTK_CHECK_VERSION(3,0,0) + const int ncols = gui.scroll_region_right - gui.scroll_region_left + 1; + const int nrows = gui.scroll_region_bot - row + 1; + const int src_nrows = nrows - num_lines; + + gui_gtk_surface_copy_rect( + FILL_X(gui.scroll_region_left), FILL_Y(row), + FILL_X(gui.scroll_region_left), FILL_Y(row + num_lines), + gui.char_width * ncols + 1, gui.char_height * src_nrows); + gui_clear_block( + gui.scroll_region_bot - num_lines + 1, gui.scroll_region_left, + gui.scroll_region_bot, gui.scroll_region_right); + gui_gtk3_redraw( + FILL_X(gui.scroll_region_left), FILL_Y(row), + gui.char_width * ncols + 1, gui.char_height * nrows); + if (!gui.by_signal) + gtk_widget_queue_draw_area(gui.drawarea, + FILL_X(gui.scroll_region_left), FILL_Y(row), + gui.char_width * ncols + 1, gui.char_height * nrows); + #else if (gui.visibility == GDK_VISIBILITY_FULLY_OBSCURED) return; /* Can't see the window */ *************** *** 5638,5643 **** --- 6799,6805 ---- gui.scroll_region_left, gui.scroll_region_bot, gui.scroll_region_right); check_copy_area(); + #endif /* !GTK_CHECK_VERSION(3,0,0) */ } /* *************** *** 5647,5652 **** --- 6809,6834 ---- void gui_mch_insert_lines(int row, int num_lines) { + #if GTK_CHECK_VERSION(3,0,0) + const int ncols = gui.scroll_region_right - gui.scroll_region_left + 1; + const int nrows = gui.scroll_region_bot - row + 1; + const int src_nrows = nrows - num_lines; + + gui_gtk_surface_copy_rect( + FILL_X(gui.scroll_region_left), FILL_Y(row + num_lines), + FILL_X(gui.scroll_region_left), FILL_Y(row), + gui.char_width * ncols + 1, gui.char_height * src_nrows); + gui_mch_clear_block( + row, gui.scroll_region_left, + row + num_lines - 1, gui.scroll_region_right); + gui_gtk3_redraw( + FILL_X(gui.scroll_region_left), FILL_Y(row), + gui.char_width * ncols + 1, gui.char_height * nrows); + if (!gui.by_signal) + gtk_widget_queue_draw_area(gui.drawarea, + FILL_X(gui.scroll_region_left), FILL_Y(row), + gui.char_width * ncols + 1, gui.char_height * nrows); + #else if (gui.visibility == GDK_VISIBILITY_FULLY_OBSCURED) return; /* Can't see the window */ *************** *** 5665,5670 **** --- 6847,6853 ---- gui_clear_block(row, gui.scroll_region_left, row + num_lines - 1, gui.scroll_region_right); check_copy_area(); + #endif /* !GTK_CHECK_VERSION(3,0,0) */ } /* *************** *** 5700,5706 **** --- 6883,6894 ---- } /* Final fallback position - use the X CUT_BUFFER0 store */ + #if GTK_CHECK_VERSION(3,0,0) + yank_cut_buffer0(GDK_WINDOW_XDISPLAY(gtk_widget_get_window(gui.mainwin)), + cbd); + #else yank_cut_buffer0(GDK_WINDOW_XDISPLAY(gui.mainwin->window), cbd); + #endif } /* *************** *** 5758,5764 **** --- 6946,6956 ---- gui_mch_menu_hidden(menu, FALSE); /* Be clever about bitfields versus true booleans here! */ + # if GTK_CHECK_VERSION(3,0,0) + if (!gtk_widget_get_sensitive(menu->id) == !grey) + # else if (!GTK_WIDGET_SENSITIVE(menu->id) == !grey) + # endif { gtk_widget_set_sensitive(menu->id, !grey); gui_mch_update(); *************** *** 5776,5782 **** --- 6968,6978 ---- if (hidden) { + # if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_visible(menu->id)) + # else if (GTK_WIDGET_VISIBLE(menu->id)) + # endif { gtk_widget_hide(menu->id); gui_mch_update(); *************** *** 5784,5790 **** --- 6980,6990 ---- } else { + # if GTK_CHECK_VERSION(3,0,0) + if (!gtk_widget_get_visible(menu->id)) + # else if (!GTK_WIDGET_VISIBLE(menu->id)) + # endif { gtk_widget_show(menu->id); gui_mch_update(); *************** *** 5812,5821 **** --- 7012,7025 ---- if (sb->id == NULL) return; + #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_visible(sb->id, flag); + #else if (flag) gtk_widget_show(sb->id); else gtk_widget_hide(sb->id); + #endif update_window_manager_hints(0, 0); } *************** *** 5828,5835 **** --- 7032,7049 ---- gui_mch_get_rgb(guicolor_T pixel) { GdkColor color; + #if GTK_CHECK_VERSION(3,0,0) + GdkRGBA rgba; + + gui_gtk_get_rgb_from_pixel(pixel, &rgba); + + color.red = rgba.red * 65535; + color.green = rgba.green * 65535; + color.blue = rgba.blue * 65535; + #else gdk_colormap_query_color(gtk_widget_get_colormap(gui.drawarea), (unsigned long)pixel, &color); + #endif return (((unsigned)color.red & 0xff00) << 8) | ((unsigned)color.green & 0xff00) *************** *** 5842,5848 **** --- 7056,7066 ---- void gui_mch_getmouse(int *x, int *y) { + #if GTK_CHECK_VERSION(3,0,0) + gui_gtk_get_pointer(gui.drawarea, x, y, NULL); + #else gdk_window_get_pointer(gui.drawarea->window, x, y, NULL); + #endif } void *************** *** 5851,5859 **** --- 7069,7083 ---- /* Sorry for the Xlib call, but we can't avoid it, since there is no * internal GDK mechanism present to accomplish this. (and for good * reason...) */ + #if GTK_CHECK_VERSION(3,0,0) + XWarpPointer(GDK_WINDOW_XDISPLAY(gtk_widget_get_window(gui.drawarea)), + (Window)0, GDK_WINDOW_XID(gtk_widget_get_window(gui.drawarea)), + 0, 0, 0U, 0U, x, y); + #else XWarpPointer(GDK_WINDOW_XDISPLAY(gui.drawarea->window), (Window)0, GDK_WINDOW_XWINDOW(gui.drawarea->window), 0, 0, 0U, 0U, x, y); + #endif } *************** *** 5874,5883 **** --- 7098,7116 ---- if (gui.pointer_hidden != hide) { gui.pointer_hidden = hide; + #if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_window(gui.drawarea) && gui.blank_pointer != NULL) + #else if (gui.drawarea->window && gui.blank_pointer != NULL) + #endif { if (hide) + #if GTK_CHECK_VERSION(3,0,0) + gdk_window_set_cursor(gtk_widget_get_window(gui.drawarea), + gui.blank_pointer); + #else gdk_window_set_cursor(gui.drawarea->window, gui.blank_pointer); + #endif else #ifdef FEAT_MOUSESHAPE mch_set_mouse_shape(last_shape); *************** *** 5919,5929 **** --- 7152,7171 ---- int id; GdkCursor *c; + # if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_window(gui.drawarea) == NULL) + # else if (gui.drawarea->window == NULL) + # endif return; if (shape == MSHAPE_HIDE || gui.pointer_hidden) + # if GTK_CHECK_VERSION(3,0,0) + gdk_window_set_cursor(gtk_widget_get_window(gui.drawarea), + gui.blank_pointer); + # else gdk_window_set_cursor(gui.drawarea->window, gui.blank_pointer); + # endif else { if (shape >= MSHAPE_NUMBERED) *************** *** 5944,5951 **** --- 7186,7201 ---- # else c = gdk_cursor_new((GdkCursorType)id); # endif + # if GTK_CHECK_VERSION(3,0,0) + gdk_window_set_cursor(gtk_widget_get_window(gui.drawarea), c); + # else gdk_window_set_cursor(gui.drawarea->window, c); + # endif + # if GTK_CHECK_VERSION(3,0,0) + g_object_unref(G_OBJECT(c)); + # else gdk_cursor_destroy(c); /* Unref, actually. Bloody GTK+ 1. */ + # endif } if (shape != MSHAPE_HIDE) last_shape = shape; *************** *** 5972,5978 **** --- 7222,7233 ---- sign = (GdkPixbuf *)sign_get_image(typenr); + # if GTK_CHECK_VERSION(3,0,0) + if (sign != NULL && gui.drawarea != NULL + && gtk_widget_get_window(gui.drawarea) != NULL) + # else if (sign != NULL && gui.drawarea != NULL && gui.drawarea->window != NULL) + # endif { int width; int height; *************** *** 6036,6041 **** --- 7291,7339 ---- xoffset = (width - SIGN_WIDTH) / 2; yoffset = (height - SIGN_HEIGHT) / 2; + # if GTK_CHECK_VERSION(3,0,0) + { + cairo_t *cr; + cairo_surface_t *bg_surf; + cairo_t *bg_cr; + cairo_surface_t *sign_surf; + cairo_t *sign_cr; + + cr = cairo_create(gui.surface); + + bg_surf = cairo_surface_create_similar(gui.surface, + cairo_surface_get_content(gui.surface), + SIGN_WIDTH, SIGN_HEIGHT); + bg_cr = cairo_create(bg_surf); + set_cairo_source_rgb_from_pixel(bg_cr, gui.bgcolor->pixel); + cairo_paint(bg_cr); + + sign_surf = cairo_surface_create_similar(gui.surface, + cairo_surface_get_content(gui.surface), + SIGN_WIDTH, SIGN_HEIGHT); + sign_cr = cairo_create(sign_surf); + gdk_cairo_set_source_pixbuf(sign_cr, sign, -xoffset, -yoffset); + cairo_paint(sign_cr); + + cairo_set_operator(sign_cr, CAIRO_OPERATOR_DEST_OVER); + cairo_set_source_surface(sign_cr, bg_surf, 0, 0); + cairo_paint(sign_cr); + + cairo_set_source_surface(cr, sign_surf, FILL_X(col), FILL_Y(row)); + cairo_paint(cr); + + cairo_destroy(sign_cr); + cairo_surface_destroy(sign_surf); + cairo_destroy(bg_cr); + cairo_surface_destroy(bg_surf); + cairo_destroy(cr); + + if (!gui.by_signal) + gtk_widget_queue_draw_area(gui.drawarea, + FILL_X(col), FILL_Y(col), width, height); + + } + # else /* !GTK_CHECK_VERSION(3,0,0) */ gdk_gc_set_foreground(gui.text_gc, gui.bgcolor); gdk_draw_rectangle(gui.drawarea->window, *************** *** 6058,6063 **** --- 7356,7362 ---- 127, GDK_RGB_DITHER_NORMAL, 0, 0); + # endif /* !GTK_CHECK_VERSION(3,0,0) */ if (need_scale) g_object_unref(sign); } *** ../vim-7.4.1401/src/if_mzsch.c 2016-02-18 21:19:17.137343416 +0100 --- src/if_mzsch.c 2016-02-23 16:23:03.848915036 +0100 *************** *** 852,858 **** --- 852,862 ---- static void CALLBACK timer_proc(HWND, UINT, UINT, DWORD); static UINT timer_id = 0; #elif defined(FEAT_GUI_GTK) + # if GTK_CHECK_VERSION(3,0,0) + static gboolean timer_proc(gpointer); + # else static gint timer_proc(gpointer); + # endif static guint timer_id = 0; #elif defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) static void timer_proc(XtPointer, XtIntervalId *); *************** *** 892,898 **** --- 896,906 ---- static void CALLBACK timer_proc(HWND hwnd UNUSED, UINT uMsg UNUSED, UINT idEvent UNUSED, DWORD dwTime UNUSED) # elif defined(FEAT_GUI_GTK) + # if GTK_CHECK_VERSION(3,0,0) + static gboolean + # else static gint + # endif timer_proc(gpointer data UNUSED) # elif defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) static void *************** *** 919,925 **** --- 927,937 ---- # if defined(FEAT_GUI_W32) timer_id = SetTimer(NULL, 0, p_mzq, timer_proc); # elif defined(FEAT_GUI_GTK) + # if GTK_CHECK_VERSION(3,0,0) + timer_id = g_timeout_add((guint)p_mzq, (GSourceFunc)timer_proc, NULL); + # else timer_id = gtk_timeout_add((guint32)p_mzq, (GtkFunction)timer_proc, NULL); + # endif # elif defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) timer_id = XtAppAddTimeOut(app_context, p_mzq, timer_proc, NULL); # elif defined(FEAT_GUI_MAC) *************** *** 935,941 **** --- 947,957 ---- # if defined(FEAT_GUI_W32) KillTimer(NULL, timer_id); # elif defined(FEAT_GUI_GTK) + # if GTK_CHECK_VERSION(3,0,0) + g_source_remove(timer_id); + # else gtk_timeout_remove(timer_id); + # endif # elif defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) XtRemoveTimeOut(timer_id); # elif defined(FEAT_GUI_MAC) *** ../vim-7.4.1401/src/mbyte.c 2016-02-23 14:52:31.885232171 +0100 --- src/mbyte.c 2016-02-23 16:23:03.848915036 +0100 *************** *** 109,115 **** #endif #if defined(FEAT_GUI_GTK) && defined(FEAT_XIM) ! # include # ifdef WIN3264 # include # else --- 109,119 ---- #endif #if defined(FEAT_GUI_GTK) && defined(FEAT_XIM) ! # if GTK_CHECK_VERSION(3,0,0) ! # include ! # else ! # include ! # endif # ifdef WIN3264 # include # else *************** *** 4941,4947 **** --- 4945,4955 ---- #endif g_return_if_fail(gui.drawarea != NULL); + #if GTK_CHECK_VERSION(3,0,0) + g_return_if_fail(gtk_widget_get_window(gui.drawarea) != NULL); + #else g_return_if_fail(gui.drawarea->window != NULL); + #endif xic = gtk_im_multicontext_new(); g_object_ref(xic); *************** *** 4955,4961 **** --- 4963,4973 ---- g_signal_connect(G_OBJECT(xic), "preedit_end", G_CALLBACK(&im_preedit_end_cb), NULL); + #if GTK_CHECK_VERSION(3,0,0) + gtk_im_context_set_client_window(xic, gtk_widget_get_window(gui.drawarea)); + #else gtk_im_context_set_client_window(xic, gui.drawarea->window); + #endif } void *************** *** 5054,5065 **** --- 5066,5086 ---- # ifdef HAVE_GTK_MULTIHEAD event = (GdkEventKey *)gdk_event_new(GDK_KEY_PRESS); + # if GTK_CHECK_VERSION(3,0,0) + g_object_ref(gtk_widget_get_window(gui.drawarea)); + /* unreffed by gdk_event_free() */ + # else g_object_ref(gui.drawarea->window); /* unreffed by gdk_event_free() */ + # endif # else event = (GdkEventKey *)g_malloc0((gulong)sizeof(GdkEvent)); event->type = GDK_KEY_PRESS; # endif + # if GTK_CHECK_VERSION(3,0,0) + event->window = gtk_widget_get_window(gui.drawarea); + # else event->window = gui.drawarea->window; + # endif event->send_event = TRUE; event->time = GDK_CURRENT_TIME; event->state = state; *** ../vim-7.4.1401/src/netbeans.c 2016-02-23 14:52:31.889232130 +0100 --- src/netbeans.c 2016-02-23 16:45:32.486822385 +0100 *************** *** 3055,3071 **** --- 3055,3110 ---- int i; int y; int x; + #if GTK_CHECK_VERSION(3,0,0) + cairo_t *cr = NULL; + #else GdkDrawable *drawable = gui.drawarea->window; + #endif if (!NETBEANS_OPEN) return; + #if GTK_CHECK_VERSION(3,0,0) + cr = cairo_create(gui.surface); + { + GdkVisual *visual = NULL; + guint32 r_mask, g_mask, b_mask; + gint r_shift, g_shift, b_shift; + + visual = gdk_window_get_visual(gtk_widget_get_window(gui.drawarea)); + if (visual != NULL) + { + 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); + + cairo_set_source_rgb(cr, + ((gui.fgcolor->red & r_mask) >> r_shift) / 255.0, + ((gui.fgcolor->green & g_mask) >> g_shift) / 255.0, + ((gui.fgcolor->blue & b_mask) >> b_shift) / 255.0); + } + } + #endif + x = 0; y = row * gui.char_height + 2; for (i = 0; i < gui.char_height - 3; i++) + #if GTK_CHECK_VERSION(3,0,0) + cairo_rectangle(cr, x+2, y++, 1, 1); + #else gdk_draw_point(drawable, gui.text_gc, x+2, y++); + #endif + #if GTK_CHECK_VERSION(3,0,0) + cairo_rectangle(cr, x+0, y, 1, 1); + cairo_rectangle(cr, x+2, y, 1, 1); + cairo_rectangle(cr, x+4, y++, 1, 1); + cairo_rectangle(cr, x+1, y, 1, 1); + cairo_rectangle(cr, x+2, y, 1, 1); + cairo_rectangle(cr, x+3, y++, 1, 1); + cairo_rectangle(cr, x+2, y, 1, 1); + #else gdk_draw_point(drawable, gui.text_gc, x+0, y); gdk_draw_point(drawable, gui.text_gc, x+2, y); gdk_draw_point(drawable, gui.text_gc, x+4, y++); *************** *** 3073,3078 **** --- 3112,3122 ---- gdk_draw_point(drawable, gui.text_gc, x+2, y); gdk_draw_point(drawable, gui.text_gc, x+3, y++); gdk_draw_point(drawable, gui.text_gc, x+2, y); + #endif + + #if GTK_CHECK_VERSION(3,0,0) + cairo_destroy(cr); + #endif } #endif /* FEAT_GUI_GTK */ *** ../vim-7.4.1401/src/structs.h 2016-02-23 14:52:31.897232046 +0100 --- src/structs.h 2016-02-23 16:23:03.852914995 +0100 *************** *** 2736,2742 **** --- 2736,2744 ---- #ifdef FEAT_GUI_GTK GtkWidget *id; /* Manage this to enable item */ GtkWidget *submenu_id; /* If this is submenu, add children here */ + # if defined(GTK_CHECK_VERSION) && !GTK_CHECK_VERSION(3,4,0) GtkWidget *tearoff_handle; + # endif GtkWidget *label; /* Used by "set wak=" code. */ #endif #ifdef FEAT_GUI_MOTIF *** ../vim-7.4.1401/src/version.c 2016-02-23 16:19:02.031424073 +0100 --- src/version.c 2016-02-23 17:11:50.998345374 +0100 *************** *** 3824,3834 **** MSG_PUTS(_("without GUI.")); #else # ifdef FEAT_GUI_GTK ! # ifdef FEAT_GUI_GNOME ! MSG_PUTS(_("with GTK2-GNOME GUI.")); # else ! MSG_PUTS(_("with GTK2 GUI.")); ! # endif # else # ifdef FEAT_GUI_MOTIF MSG_PUTS(_("with X11-Motif GUI.")); --- 3826,3840 ---- MSG_PUTS(_("without GUI.")); #else # ifdef FEAT_GUI_GTK ! # ifdef USE_GTK3 ! MSG_PUTS(_("with GTK3 GUI.")); # else ! # ifdef FEAT_GUI_GNOME ! MSG_PUTS(_("with GTK2-GNOME GUI.")); ! # else ! MSG_PUTS(_("with GTK2 GUI.")); ! # endif ! # endif # else # ifdef FEAT_GUI_MOTIF MSG_PUTS(_("with X11-Motif GUI.")); *** ../vim-7.4.1401/src/version.c 2016-02-23 16:19:02.031424073 +0100 --- src/version.c 2016-02-23 17:11:50.998345374 +0100 *************** *** 750,751 **** --- 750,753 ---- { /* Add new patch number below this line */ + /**/ + 1402, /**/ -- CRONE: Who sent you? ARTHUR: The Knights Who Say Ni! CRONE: Aaaagh! (she looks around in rear) No! We have no shrubberies here. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///