0
0
mirror of https://github.com/vim/vim.git synced 2025-09-01 21:03:39 -04:00

patch 7.4.1402

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

View File

@ -7315,6 +7315,7 @@ gui_athena Compiled with Athena GUI.
gui_gnome Compiled with Gnome support (gui_gtk is also defined).
gui_gtk Compiled with GTK+ GUI (any version).
gui_gtk2 Compiled with GTK+ 2 GUI (gui_gtk is also defined).
gui_gtk3 Compiled with GTK+ 3 GUI (gui_gtk is also defined).
gui_mac Compiled with Macintosh GUI.
gui_motif Compiled with Motif GUI.
gui_photon Compiled with Photon GUI.

View File

@ -25,7 +25,7 @@ Other GUI documentation:
First you must make sure you actually have a version of Vim with the GUI code
included. You can check this with the ":version" command, it says "with xxx
GUI", where "xxx" is X11-Motif, X11-Athena, Photon, GTK, GTK2, etc., or
GUI", where "xxx" is X11-Motif, X11-Athena, Photon, GTK2, GTK3, etc., or
"MS-Windows 32 bit GUI version".
How to start the GUI depends on the system used. Mostly you can run the
@ -514,11 +514,14 @@ a menu entry. Hit <Enter> to execute it. Hit <Esc> if you want to cancel.
This does require the |+menu| feature enabled at compile time.
*tear-off-menus*
GTK+ and Motif support Tear-off menus. These are sort of sticky menus or
GTK+ 2 and Motif support Tear-off menus. These are sort of sticky menus or
pop-up menus that are present all the time. If the resizing does not work
correctly, this may be caused by using something like "Vim*geometry" in the
defaults. Use "Vim.geometry" instead.
As to GTK+ 3, tear-off menus have been deprecated since GTK+ 3.4.
Accordingly, they are disabled if gvim is linked against GTK+ 3.4 or later.
The Win32 GUI version emulates Motif's tear-off menus. Actually, a Motif user
will spot the differences easily, but hopefully they're just as useful. You
can also use the |:tearoff| command together with |hidden-menus| to create
@ -650,8 +653,8 @@ When no or zero priority is given, 500 is used.
The priority for the PopUp menu is not used.
The Help menu will be placed on the far right side of the menu bar on systems
which support this (Motif and GTK+). For GTK+ 2, this is not done anymore
because right-aligning the Help menu is now discouraged UI design.
which support this (Motif and GTK+). For GTK+ 2 and 3, this is not done
anymore because right-aligning the Help menu is now discouraged UI design.
You can use a priority higher than 9999, to make it go after the Help menu,
but that is non-standard and is discouraged. The highest possible priority is

View File

@ -369,6 +369,16 @@ Write this in the file ~/.gtkrc and it will be used by GTK+. For GTK+ 2
you might have to use the file ~/.gtkrc-2.0 instead, depending on your
distribution.
For GTK+ 3, an effect similar to the above can be obtained by adding the
following snippet of CSS code to $XDG_HOME_DIR/gtk-3.0/gtk.css (usually,
$HOME/.config/gtk-3.0/gtk.css):
>
.tooltip {
background-color: #ffffcc;
color: #000000;
}
<
Using Vim as a GTK+ plugin *gui-gtk-socketid*
When the GTK+ version of Vim starts up normally, it creates its own top level

264
src/auto/configure vendored
View File

@ -821,6 +821,7 @@ with_x
enable_gui
enable_gtk2_check
enable_gnome_check
enable_gtk3_check
enable_motif_check
enable_athena_check
enable_nextaw_check
@ -1481,9 +1482,10 @@ Optional Features:
--enable-hangulinput Include Hangul input support.
--enable-xim Include XIM input support.
--enable-fontset Include X fontset output support.
--enable-gui=OPTS X11 GUI default=auto OPTS=auto/no/gtk2/gnome2/motif/athena/neXtaw/photon/carbon
--enable-gui=OPTS X11 GUI default=auto OPTS=auto/no/gtk2/gnome2/gtk3/motif/athena/neXtaw/photon/carbon
--enable-gtk2-check If auto-select GUI, check for GTK+ 2 default=yes
--enable-gnome-check If GTK GUI, check for GNOME default=no
--enable-gtk3-check If auto-select GUI, check for GTK+ 3 default=yes
--enable-motif-check If auto-select GUI, check for Motif default=yes
--enable-athena-check If auto-select GUI, check for Athena default=yes
--enable-nextaw-check If auto-select GUI, check for neXtaw default=yes
@ -4355,7 +4357,7 @@ fi
if test "x$CARBON" = "xyes"; then
if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk2; then
if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk2 -a "X$enable_gui" != Xgtk3; then
with_x=no
fi
fi
@ -8606,6 +8608,9 @@ $as_echo "GTK+ 2.x GUI support" >&6; }
$as_echo "GNOME 2.x GUI support" >&6; }
SKIP_GNOME=
SKIP_GTK2=;;
gtk3) { $as_echo "$as_me:${as_lineno-$LINENO}: result: GTK+ 3.x GUI support" >&5
$as_echo "GTK+ 3.x GUI support" >&6; }
SKIP_GTK3=;;
motif) { $as_echo "$as_me:${as_lineno-$LINENO}: result: Motif GUI support" >&5
$as_echo "Motif GUI support" >&6; }
SKIP_MOTIF=;;
@ -8657,6 +8662,23 @@ $as_echo "$enable_gnome_check" >&6; }
fi
fi
if test "x$SKIP_GTK3" != "xYES" -a "$enable_gui_canon" != "gtk3"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether or not to look for GTK+ 3" >&5
$as_echo_n "checking whether or not to look for GTK+ 3... " >&6; }
# Check whether --enable-gtk3-check was given.
if test "${enable_gtk3_check+set}" = set; then :
enableval=$enable_gtk3_check;
else
enable_gtk3_check="yes"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_gtk3_check" >&5
$as_echo "$enable_gtk3_check" >&6; }
if test "x$enable_gtk3_check" = "xno"; then
SKIP_GTK3=YES
fi
fi
if test "x$SKIP_MOTIF" != "xYES" -a "$enable_gui_canon" != "motif"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether or not to look for Motif" >&5
$as_echo_n "checking whether or not to look for Motif... " >&6; }
@ -8831,13 +8853,13 @@ fi
if test "X$GTK_CONFIG" != "Xno" -o "X$PKG_CONFIG" != "Xno"; then
{
min_gtk_version=2.2.0
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK - version >= $min_gtk_version" >&5
$as_echo_n "checking for GTK - version >= $min_gtk_version... " >&6; }
no_gtk=""
if (test "X$SKIP_GTK2" != "XYES" -a "X$PKG_CONFIG" != "Xno") \
&& $PKG_CONFIG --exists gtk+-2.0; then
{
min_gtk_version=2.2.0
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK - version >= $min_gtk_version" >&5
$as_echo_n "checking for GTK - version >= $min_gtk_version... " >&6; }
GTK_CFLAGS=`$PKG_CONFIG --cflags gtk+-2.0`
GTK_LIBDIR=`$PKG_CONFIG --libs-only-L gtk+-2.0`
GTK_LIBS=`$PKG_CONFIG --libs gtk+-2.0`
@ -8848,6 +8870,23 @@ $as_echo_n "checking for GTK - version >= $min_gtk_version... " >&6; }
gtk_micro_version=`$PKG_CONFIG --modversion gtk+-2.0 | \
sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'`
}
elif (test "X$SKIP_GTK3" != "XYES" -a "X$PKG_CONFIG" != "Xno") \
&& $PKG_CONFIG --exists gtk+-3.0; then
{
min_gtk_version=2.2.0
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK - version >= $min_gtk_version" >&5
$as_echo_n "checking for GTK - version >= $min_gtk_version... " >&6; }
GTK_CFLAGS=`$PKG_CONFIG --cflags gtk+-3.0`
GTK_LIBDIR=`$PKG_CONFIG --libs-only-L gtk+-3.0`
GTK_LIBS=`$PKG_CONFIG --libs gtk+-3.0`
gtk_major_version=`$PKG_CONFIG --modversion gtk+-3.0 | \
sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'`
gtk_minor_version=`$PKG_CONFIG --modversion gtk+-3.0 | \
sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'`
gtk_micro_version=`$PKG_CONFIG --modversion gtk+-3.0 | \
sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'`
}
else
no_gtk=yes
fi
@ -8943,6 +8982,7 @@ $as_echo "no" >&6; }
rm -f conf.gtktest
if test "x$GTK_CFLAGS" != "x"; then
SKIP_GTK3=YES
SKIP_ATHENA=YES
SKIP_NEXTAW=YES
SKIP_MOTIF=YES
@ -9044,6 +9084,218 @@ $as_echo "not found" >&6; }
fi
fi
if test -z "$SKIP_GTK3"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking --disable-gtktest argument" >&5
$as_echo_n "checking --disable-gtktest argument... " >&6; }
# Check whether --enable-gtktest was given.
if test "${enable_gtktest+set}" = set; then :
enableval=$enable_gtktest;
else
enable_gtktest=yes
fi
if test "x$enable_gtktest" = "xyes" ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test enabled" >&5
$as_echo "gtk test enabled" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test disabled" >&5
$as_echo "gtk test disabled" >&6; }
fi
if test "X$PKG_CONFIG" = "X"; then
# Extract the first word of "pkg-config", so it can be a program name with args.
set dummy pkg-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_PKG_CONFIG+:} false; then :
$as_echo_n "(cached) " >&6
else
case $PKG_CONFIG in
[\\/]* | ?:[\\/]*)
ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
;;
esac
fi
PKG_CONFIG=$ac_cv_path_PKG_CONFIG
if test -n "$PKG_CONFIG"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
$as_echo "$PKG_CONFIG" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test "x$PKG_CONFIG" != "xno"; then
if test "X$GTK_CONFIG" != "Xno" -o "X$PKG_CONFIG" != "Xno"; then
{
no_gtk=""
if (test "X$SKIP_GTK2" != "XYES" -a "X$PKG_CONFIG" != "Xno") \
&& $PKG_CONFIG --exists gtk+-2.0; then
{
min_gtk_version=3.0.0
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK - version >= $min_gtk_version" >&5
$as_echo_n "checking for GTK - version >= $min_gtk_version... " >&6; }
GTK_CFLAGS=`$PKG_CONFIG --cflags gtk+-2.0`
GTK_LIBDIR=`$PKG_CONFIG --libs-only-L gtk+-2.0`
GTK_LIBS=`$PKG_CONFIG --libs gtk+-2.0`
gtk_major_version=`$PKG_CONFIG --modversion gtk+-2.0 | \
sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'`
gtk_minor_version=`$PKG_CONFIG --modversion gtk+-2.0 | \
sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'`
gtk_micro_version=`$PKG_CONFIG --modversion gtk+-2.0 | \
sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'`
}
elif (test "X$SKIP_GTK3" != "XYES" -a "X$PKG_CONFIG" != "Xno") \
&& $PKG_CONFIG --exists gtk+-3.0; then
{
min_gtk_version=3.0.0
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK - version >= $min_gtk_version" >&5
$as_echo_n "checking for GTK - version >= $min_gtk_version... " >&6; }
GTK_CFLAGS=`$PKG_CONFIG --cflags gtk+-3.0`
GTK_LIBDIR=`$PKG_CONFIG --libs-only-L gtk+-3.0`
GTK_LIBS=`$PKG_CONFIG --libs gtk+-3.0`
gtk_major_version=`$PKG_CONFIG --modversion gtk+-3.0 | \
sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'`
gtk_minor_version=`$PKG_CONFIG --modversion gtk+-3.0 | \
sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'`
gtk_micro_version=`$PKG_CONFIG --modversion gtk+-3.0 | \
sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'`
}
else
no_gtk=yes
fi
if test "x$enable_gtktest" = "xyes" -a "x$no_gtk" = "x"; then
{
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $GTK_CFLAGS"
LIBS="$LIBS $GTK_LIBS"
rm -f conf.gtktest
if test "$cross_compiling" = yes; then :
echo $ac_n "cross compiling; assumed OK... $ac_c"
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <gtk/gtk.h>
#include <stdio.h>
#if STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#endif
int
main ()
{
int major, minor, micro;
char *tmp_version;
system ("touch conf.gtktest");
/* HP/UX 9 (%@#!) writes to sscanf strings */
tmp_version = g_strdup("$min_gtk_version");
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
printf("%s, bad version string\n", "$min_gtk_version");
exit(1);
}
if ((gtk_major_version > major) ||
((gtk_major_version == major) && (gtk_minor_version > minor)) ||
((gtk_major_version == major) && (gtk_minor_version == minor) &&
(gtk_micro_version >= micro)))
{
return 0;
}
return 1;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
else
no_gtk=yes
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
}
fi
if test "x$no_gtk" = x ; then
if test "x$enable_gtktest" = "xyes"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes; found version $gtk_major_version.$gtk_minor_version.$gtk_micro_version" >&5
$as_echo "yes; found version $gtk_major_version.$gtk_minor_version.$gtk_micro_version" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found version $gtk_major_version.$gtk_minor_version.$gtk_micro_version" >&5
$as_echo "found version $gtk_major_version.$gtk_minor_version.$gtk_micro_version" >&6; }
fi
GUI_LIB_LOC="$GTK_LIBDIR"
GTK_LIBNAME="$GTK_LIBS"
GUI_INC_LOC="$GTK_CFLAGS"
else
{
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
GTK_CFLAGS=""
GTK_LIBS=""
:
}
fi
}
else
GTK_CFLAGS=""
GTK_LIBS=""
:
fi
rm -f conf.gtktest
if test "x$GTK_CFLAGS" != "x"; then
SKIP_GTK2=YES
SKIP_GNOME=YES
SKIP_ATHENA=YES
SKIP_NEXTAW=YES
SKIP_MOTIF=YES
GUITYPE=GTK
$as_echo "#define HAVE_GTK_MULTIHEAD 1" >>confdefs.h
$as_echo "#define USE_GTK3 1" >>confdefs.h
fi
fi
fi
if test "x$GUITYPE" = "xGTK"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking version of Gdk-Pixbuf" >&5
$as_echo_n "checking version of Gdk-Pixbuf... " >&6; }
@ -9546,7 +9798,7 @@ done
fi
if test -z "$SKIP_ATHENA" -o -z "$SKIP_NEXTAW" -o -z "$SKIP_MOTIF" -o -z "$SKIP_GTK2"; then
if test -z "$SKIP_ATHENA" -o -z "$SKIP_NEXTAW" -o -z "$SKIP_MOTIF" -o -z "$SKIP_GTK2" -o -z "$SKIP_GTK3"; then
cppflags_save=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
for ac_header in X11/xpm.h X11/Sunkeysym.h

View File

@ -361,6 +361,17 @@ messageFromNetbeans(XtPointer clientData,
#endif
#ifdef FEAT_GUI_GTK
# if GTK_CHECK_VERSION(3,0,0)
static gboolean
messageFromNetbeans(GIOChannel *unused1 UNUSED,
GIOCondition unused2 UNUSED,
gpointer clientData)
{
channel_read_fd(GPOINTER_TO_INT(clientData));
return TRUE; /* Return FALSE instead in case the event source is to
* be removed after this function returns. */
}
# else
static void
messageFromNetbeans(gpointer clientData,
gint unused1 UNUSED,
@ -368,6 +379,7 @@ messageFromNetbeans(gpointer clientData,
{
channel_read_fd((int)(long)clientData);
}
# endif
#endif
static void
@ -388,12 +400,27 @@ channel_gui_register_one(channel_T *channel, int part)
/* Tell gdk we are interested in being called when there
* is input on the editor connection socket. */
if (channel->ch_part[part].ch_inputHandler == 0)
# if GTK_CHECK_VERSION(3,0,0)
{
GIOChannel *chnnl = g_io_channel_unix_new(
(gint)channel->ch_part[part].ch_fd);
channel->ch_part[part].ch_inputHandler = g_io_add_watch(
chnnl,
G_IO_IN|G_IO_HUP|G_IO_ERR|G_IO_PRI,
messageFromNetbeans,
GINT_TO_POINTER(channel->ch_part[part].ch_fd));
g_io_channel_unref(chnnl);
}
# else
channel->ch_part[part].ch_inputHandler = gdk_input_add(
(gint)channel->ch_part[part].ch_fd,
(GdkInputCondition)
((int)GDK_INPUT_READ + (int)GDK_INPUT_EXCEPTION),
messageFromNetbeans,
(gpointer)(long)channel->ch_part[part].ch_fd);
# endif
# else
# ifdef FEAT_GUI_W32
/* Tell Windows we are interested in receiving message when there
@ -457,7 +484,11 @@ channel_gui_unregister(channel_T *channel)
# ifdef FEAT_GUI_GTK
if (channel->ch_part[part].ch_inputHandler != 0)
{
# if GTK_CHECK_VERSION(3,0,0)
g_source_remove(channel->ch_part[part].ch_inputHandler);
# else
gdk_input_remove(channel->ch_part[part].ch_inputHandler);
# endif
channel->ch_part[part].ch_inputHandler = 0;
}
# else
@ -606,7 +637,7 @@ channel_open(
fd_set wfds;
#if defined(__APPLE__) && __APPLE__ == 1
# define PASS_RFDS
fd_set rfds;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(sd, &rfds);

View File

@ -460,3 +460,6 @@
/* Define if GResource is used to load icons */
#undef USE_GRESOURCE
/* Define if GTK+ GUI is to be linked against GTK+ 3 */
#undef USE_GTK3

View File

@ -213,7 +213,7 @@ if test "`(uname) 2>/dev/null`" = Darwin; then
dnl or Motif, Athena or GTK GUI is used.
AC_CHECK_HEADER(Carbon/Carbon.h, CARBON=yes)
if test "x$CARBON" = "xyes"; then
if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk2; then
if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk2 -a "X$enable_gui" != Xgtk3; then
with_x=no
fi
fi
@ -2198,7 +2198,7 @@ test "x$with_x" = xno -a "x$MACOSX" != "xyes" -a "x$QNX" != "xyes" && enable_gui
AC_MSG_CHECKING(--enable-gui argument)
AC_ARG_ENABLE(gui,
[ --enable-gui[=OPTS] X11 GUI [default=auto] [OPTS=auto/no/gtk2/gnome2/motif/athena/neXtaw/photon/carbon]], , enable_gui="auto")
[ --enable-gui[=OPTS] X11 GUI [default=auto] [OPTS=auto/no/gtk2/gnome2/gtk3/motif/athena/neXtaw/photon/carbon]], , enable_gui="auto")
dnl Canonicalize the --enable-gui= argument so that it can be easily compared.
dnl Do not use character classes for portability with old tools.
@ -2256,6 +2256,8 @@ else
gnome2) AC_MSG_RESULT(GNOME 2.x GUI support)
SKIP_GNOME=
SKIP_GTK2=;;
gtk3) AC_MSG_RESULT(GTK+ 3.x GUI support)
SKIP_GTK3=;;
motif) AC_MSG_RESULT(Motif GUI support)
SKIP_MOTIF=;;
athena) AC_MSG_RESULT(Athena GUI support)
@ -2291,6 +2293,17 @@ if test "x$SKIP_GNOME" != "xYES" -a "$enable_gui_canon" != "gnome2"; then
fi
fi
if test "x$SKIP_GTK3" != "xYES" -a "$enable_gui_canon" != "gtk3"; then
AC_MSG_CHECKING(whether or not to look for GTK+ 3)
AC_ARG_ENABLE(gtk3-check,
[ --enable-gtk3-check If auto-select GUI, check for GTK+ 3 [default=yes]],
, enable_gtk3_check="yes")
AC_MSG_RESULT($enable_gtk3_check)
if test "x$enable_gtk3_check" = "xno"; then
SKIP_GTK3=YES
fi
fi
if test "x$SKIP_MOTIF" != "xYES" -a "$enable_gui_canon" != "motif"; then
AC_MSG_CHECKING(whether or not to look for Motif)
AC_ARG_ENABLE(motif-check,
@ -2379,12 +2392,12 @@ AC_DEFUN(AM_PATH_GTK,
[
if test "X$GTK_CONFIG" != "Xno" -o "X$PKG_CONFIG" != "Xno"; then
{
min_gtk_version=ifelse([$1], ,2.2.0,$1)
AC_MSG_CHECKING(for GTK - version >= $min_gtk_version)
no_gtk=""
if (test "X$SKIP_GTK2" != "XYES" -a "X$PKG_CONFIG" != "Xno") \
&& $PKG_CONFIG --exists gtk+-2.0; then
{
min_gtk_version=ifelse([$1], ,2.2.0,$1)
AC_MSG_CHECKING(for GTK - version >= $min_gtk_version)
dnl We should be using PKG_CHECK_MODULES() instead of this hack.
dnl But I guess the dependency on pkgconfig.m4 is not wanted or
dnl something like that.
@ -2398,6 +2411,22 @@ AC_DEFUN(AM_PATH_GTK,
gtk_micro_version=`$PKG_CONFIG --modversion gtk+-2.0 | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
}
elif (test "X$SKIP_GTK3" != "XYES" -a "X$PKG_CONFIG" != "Xno") \
&& $PKG_CONFIG --exists gtk+-3.0; then
{
min_gtk_version=ifelse([$1], ,3.0.0,$1)
AC_MSG_CHECKING(for GTK - version >= $min_gtk_version)
GTK_CFLAGS=`$PKG_CONFIG --cflags gtk+-3.0`
GTK_LIBDIR=`$PKG_CONFIG --libs-only-L gtk+-3.0`
GTK_LIBS=`$PKG_CONFIG --libs gtk+-3.0`
gtk_major_version=`$PKG_CONFIG --modversion gtk+-3.0 | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
gtk_minor_version=`$PKG_CONFIG --modversion gtk+-3.0 | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
gtk_micro_version=`$PKG_CONFIG --modversion gtk+-3.0 | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
}
else
no_gtk=yes
fi
@ -2573,6 +2602,7 @@ if test -z "$SKIP_GTK2"; then
GTK_LIBNAME="$GTK_LIBS"
GUI_INC_LOC="$GTK_CFLAGS"], )
if test "x$GTK_CFLAGS" != "x"; then
SKIP_GTK3=YES
SKIP_ATHENA=YES
SKIP_NEXTAW=YES
SKIP_MOTIF=YES
@ -2601,6 +2631,44 @@ if test -z "$SKIP_GTK2"; then
fi
fi
dnl ---------------------------------------------------------------------------
dnl Check for GTK3.
dnl ---------------------------------------------------------------------------
if test -z "$SKIP_GTK3"; then
AC_MSG_CHECKING(--disable-gtktest argument)
AC_ARG_ENABLE(gtktest, [ --disable-gtktest Do not try to compile and run a test GTK program],
, enable_gtktest=yes)
if test "x$enable_gtktest" = "xyes" ; then
AC_MSG_RESULT(gtk test enabled)
else
AC_MSG_RESULT(gtk test disabled)
fi
if test "X$PKG_CONFIG" = "X"; then
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
fi
if test "x$PKG_CONFIG" != "xno"; then
AM_PATH_GTK(3.0.0,
[GUI_LIB_LOC="$GTK_LIBDIR"
GTK_LIBNAME="$GTK_LIBS"
GUI_INC_LOC="$GTK_CFLAGS"], )
if test "x$GTK_CFLAGS" != "x"; then
SKIP_GTK2=YES
SKIP_GNOME=YES
SKIP_ATHENA=YES
SKIP_NEXTAW=YES
SKIP_MOTIF=YES
GUITYPE=GTK
AC_SUBST(GTK_LIBNAME)
AC_DEFINE(HAVE_GTK_MULTIHEAD)
AC_DEFINE(USE_GTK3)
fi
fi
fi
dnl Check the version of Gdk-Pixbuf. If the version is 2.31 or later and
dnl glib-compile-resources is found in PATH, use GResource.
if test "x$GUITYPE" = "xGTK"; then
@ -2823,7 +2891,7 @@ if test "$enable_xsmp" = "yes"; then
fi
if test -z "$SKIP_ATHENA" -o -z "$SKIP_NEXTAW" -o -z "$SKIP_MOTIF" -o -z "$SKIP_GTK2"; then
if test -z "$SKIP_ATHENA" -o -z "$SKIP_NEXTAW" -o -z "$SKIP_MOTIF" -o -z "$SKIP_GTK2" -o -z "$SKIP_GTK3"; then
dnl Check for X11/xpm.h and X11/Sunkeysym.h with the GUI include path
cppflags_save=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $X_CFLAGS"

View File

@ -13671,7 +13671,11 @@ f_has(typval_T *argvars, typval_T *rettv)
#endif
#ifdef FEAT_GUI_GTK
"gui_gtk",
# ifdef USE_GTK3
"gui_gtk3",
# else
"gui_gtk2",
# endif
#endif
#ifdef FEAT_GUI_GNOME
"gui_gnome",

View File

@ -359,7 +359,9 @@ typedef struct Gui
#endif
#ifdef FEAT_GUI_GTK
# ifndef USE_GTK3
int visibility; /* Is shell partially/fully obscured? */
# endif
GdkCursor *blank_pointer; /* Blank pointer */
/* X Resources */
@ -381,7 +383,12 @@ typedef struct Gui
GdkColor *fgcolor; /* GDK-styled foreground color */
GdkColor *bgcolor; /* GDK-styled background color */
GdkColor *spcolor; /* GDK-styled special color */
# ifdef USE_GTK3
cairo_surface_t *surface; /* drawarea surface */
gboolean by_signal; /* cause of draw operation */
# else
GdkGC *text_gc; /* cached GC for normal text */
# endif
PangoContext *text_context; /* the context used for all text */
PangoFont *ascii_font; /* cached font for ASCII strings */
PangoGlyphString *ascii_glyphs; /* cached code point -> glyph map */

View File

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

View File

@ -11,7 +11,11 @@
#define GUI_BEVAL_H
#ifdef FEAT_GUI_GTK
# include <gtk/gtkwidget.h>
# ifdef USE_GTK3
# include <gtk/gtk.h>
# else
# include <gtk/gtkwidget.h>
# endif
#else
# if defined(FEAT_GUI_X11)
# include <X11/Intrinsic.h>

File diff suppressed because it is too large Load Diff

View File

@ -19,13 +19,19 @@
* 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 <kazunobu.kuriyama@gmail.com>
*/
#include "vim.h"
#include <gtk/gtk.h> /* without this it compiles, but gives errors at
runtime! */
#include "gui_gtk_f.h"
#include <gtk/gtksignal.h>
#if !GTK_CHECK_VERSION(3,0,0)
# include <gtk/gtksignal.h>
#endif
#ifdef WIN3264
# include <gdk/gdkwin32.h>
#else
@ -52,10 +58,23 @@ static void gtk_form_unrealize(GtkWidget *widget);
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,22 +92,27 @@ static void gtk_form_position_child(GtkForm *form,
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,7 +122,11 @@ gtk_form_new(void)
{
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,8 +148,12 @@ gtk_form_put(GtkForm *form,
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,13 +163,24 @@ gtk_form_put(GtkForm *form,
* 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,6 +236,9 @@ gtk_form_thaw(GtkForm *form)
/* 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,6 +259,7 @@ gtk_form_get_type(void)
}
return form_type;
}
#endif /* !GTK_CHECK_VERSION(3,0,0) */
static void
gtk_form_class_init(GtkFormClass *klass)
@ -223,14 +270,25 @@ gtk_form_class_init(GtkFormClass *klass)
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,15 +297,22 @@ gtk_form_class_init(GtkFormClass *klass)
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,40 +332,92 @@ gtk_form_realize(GtkWidget *widget)
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,7 +425,11 @@ gtk_form_realize(GtkWidget *widget)
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,17 +453,30 @@ gtk_form_map(GtkWidget *widget)
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,12 +503,21 @@ gtk_form_unrealize(GtkWidget *widget)
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,20 +528,33 @@ gtk_form_unrealize(GtkWidget *widget)
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,25 +566,71 @@ gtk_form_size_request(GtkWidget *widget, GtkRequisition *requisition)
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)
{
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,20 +646,81 @@ gtk_form_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
}
}
#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,6 +760,7 @@ gtk_form_expose(GtkWidget *widget, GdkEventExpose *event)
return FALSE;
}
#endif /* !GTK_CHECK_VERSION(3,0,0) */
/* Container method
*/
@ -522,12 +786,22 @@ gtk_form_remove(GtkContainer *container, GtkWidget *widget)
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(&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
/* FIXME: This will cause problems for reparenting NO_WINDOW
* widgets out of a GtkForm
@ -536,7 +810,10 @@ gtk_form_remove(GtkContainer *container, GtkWidget *widget)
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,7 +854,11 @@ gtk_form_attach_child_window(GtkForm *form, GtkFormChild *child)
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,34 +869,75 @@ gtk_form_attach_child_window(GtkForm *form, GtkFormChild *child)
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(&gtk_form_child_map), child);
g_signal_connect(G_OBJECT(child->widget), "unmap",
G_CALLBACK(&gtk_form_child_unmap), child);
#else
gtk_signal_connect(GTK_OBJECT(child->widget), "map",
GTK_SIGNAL_FUNC(&gtk_form_child_map), child);
gtk_signal_connect(GTK_OBJECT(child->widget), "unmap",
GTK_SIGNAL_FUNC(&gtk_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,8 +949,14 @@ gtk_form_realize_child(GtkForm *form, GtkFormChild *child)
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,9 +974,18 @@ gtk_form_position_child(GtkForm *form, GtkFormChild *child,
{
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,15 +996,31 @@ gtk_form_position_child(GtkForm *form, GtkFormChild *child,
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,8 +1032,13 @@ gtk_form_position_child(GtkForm *form, GtkFormChild *child,
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,7 +1049,11 @@ gtk_form_position_child(GtkForm *form, GtkFormChild *child,
{
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,6 +1079,7 @@ gtk_form_position_children(GtkForm *form)
* 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,7 +1146,9 @@ gtk_form_main_filter(GdkXEvent *gdk_xevent,
}
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,13 +1156,18 @@ gtk_form_set_static_gravity(GdkWindow *window, gboolean use_static)
* 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,11 +1181,24 @@ gtk_form_send_configure(GtkForm *form)
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,4 +1224,3 @@ gtk_form_child_unmap(GtkWidget *widget UNUSED, gpointer user_data)
child->mapped = FALSE;
gdk_window_hide(child->window);
}

View File

@ -9,8 +9,12 @@
#ifndef __GTK_FORM_H__
#define __GTK_FORM_H__
#ifdef USE_GTK3
#include <gtk/gtk.h>
#else
#include <gdk/gdk.h>
#include <gtk/gtkcontainer.h>
#endif
#ifdef __cplusplus
@ -18,10 +22,17 @@ extern "C" {
#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,13 +44,17 @@ struct _GtkForm
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,7 +64,11 @@ struct _GtkFormClass
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);

File diff suppressed because it is too large Load Diff

View File

@ -852,7 +852,11 @@ static int mz_threads_allow = 0;
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,7 +896,11 @@ static void remove_timer(void);
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,7 +927,11 @@ setup_timer(void)
# 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,7 +947,11 @@ remove_timer(void)
# 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)

View File

@ -109,7 +109,11 @@
#endif
#if defined(FEAT_GUI_GTK) && defined(FEAT_XIM)
# include <gdk/gdkkeysyms.h>
# if GTK_CHECK_VERSION(3,0,0)
# include <gdk/gdkkeysyms-compat.h>
# else
# include <gdk/gdkkeysyms.h>
# endif
# ifdef WIN3264
# include <gdk/gdkwin32.h>
# else
@ -4941,7 +4945,11 @@ xim_init(void)
#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,7 +4963,11 @@ xim_init(void)
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,12 +5066,21 @@ im_synthesize_keypress(unsigned int keyval, unsigned int state)
# 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;

View File

@ -3055,17 +3055,56 @@ netbeans_draw_multisign_indicator(int row)
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,6 +3112,11 @@ netbeans_draw_multisign_indicator(int row)
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 */

View File

@ -2736,7 +2736,9 @@ struct VimMenu
#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

View File

@ -748,6 +748,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1402,
/**/
1401,
/**/
@ -3824,11 +3826,15 @@ list_version(void)
MSG_PUTS(_("without GUI."));
#else
# ifdef FEAT_GUI_GTK
# ifdef FEAT_GUI_GNOME
MSG_PUTS(_("with GTK2-GNOME GUI."));
# ifdef USE_GTK3
MSG_PUTS(_("with GTK3 GUI."));
# else
MSG_PUTS(_("with GTK2 GUI."));
# endif
# 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."));