aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2016-01-31 01:55:27 +0100
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2016-01-31 02:21:02 +0100
commitff17c72962d76986b48f3ab05e6ca9e7b3a4f78e (patch)
tree4c21cc1ad64e7ba9d0429defb4abf652ea4c822a
parentd7279189cbd51d2d1b5dee36a4fb09f3388801e0 (diff)
downloadsciteco-ff17c72962d76986b48f3ab05e6ca9e7b3a4f78e.tar.gz
updated to Gtk+ 3 and revamped the Gtk interface's popup widget
* depend on Gtk+ 3.10. If necessary older versions should also be supportable. GtkOverlay was already introduced in v3.2 * A fallback for GtkFlowBox is compiled in if the Gtk installation is too old. This applies even to Ubuntu 14.04 which still runs Gtk v3.10. * the threading the Gtk UI is left as it is for the time being even though the synchronization mechanism has been deprecated. Alternative approaches have to be tried out and benchmarked. * Completely revamped the GtkInfoPopup widget. It is now as powerful as the Curses UI's popup widget. * A GtkOverlay is used instead of the top-level window hack in the Gtk2 version. * GtkFlowBox is used to lay out the columns of the popup. * I had to work around restrictions of GtkScrolledWindow by writing my own poor-mans scrolled window which handles size requests correctly. * The popup window no longer overflows the screen size, instead we scroll. * Scrolling pagewise is finally supported. Wraps at the end of a list just like the Curses UI. * Instead of using only two stock icons, we now use GIO to get file and directory icons for the current theme. This looks even better. * The GtkFlowBox allows selections which can be used for mouse interaction later. But this is not yet implemented. * Theming of the popup widget and command line is still not performed correctly.
-rw-r--r--INSTALL4
-rw-r--r--README3
-rw-r--r--TODO1
-rw-r--r--configure.ac17
-rw-r--r--scintilla.am2
-rw-r--r--src/Makefile.am7
-rw-r--r--src/gtk-info-popup.gob270
-rw-r--r--src/interface-gtk.cpp78
-rw-r--r--src/interface-gtk.h12
9 files changed, 269 insertions, 125 deletions
diff --git a/INSTALL b/INSTALL
index d8e80d7..2f1aeff 100644
--- a/INSTALL
+++ b/INSTALL
@@ -28,8 +28,8 @@ SciTECO Build and Runtime Dependencies
* PDCurses/EMCurses (https://github.com/rhaberkorn/emcurses).
* other curses implementations might work as well but are untested
* When choosing the GTK interface:
- * GTK+ 2: http://www.gtk.org/
- * GObject Builder: http://www.jirka.org/gob.html
+ * GTK+ v3.10 or later: http://www.gtk.org/
+ * GObject Builder v2.0.20 or later: http://www.jirka.org/gob.html
* Groff (only when formatting HTML manuals)
* Doxygen (only when generating developer documentation)
diff --git a/README b/README
index 4e6b5b5..e687f6a 100644
--- a/README
+++ b/README
@@ -15,8 +15,7 @@ When you delete a character from the end of the command line macro (called rubou
side-effects of that character which may be a command or part of a command, are undone.
SciTECO uses the [Scintilla](http://www.scintilla.org/) editor component and supports
-GTK+ 2 as well as Curses frontends (using [Scinterm](http://foicica.com/scinterm/)).
-Currently, the Curses frontend is recommended.
+GTK+ 3 as well as Curses frontends (using [Scinterm](http://foicica.com/scinterm/)).
The Curses frontend is verified to work with [ncurses](https://www.gnu.org/software/ncurses/),
[PDCurses/XCurses](http://pdcurses.sourceforge.net/), the
diff --git a/TODO b/TODO
index 6b0241c..cb8fef4 100644
--- a/TODO
+++ b/TODO
@@ -121,7 +121,6 @@ Features:
* A Scintilla view will allow syntax highlighting
* command line could highlight dead branches (e.g. gray them out)
* improve GTK interface
- * shell-like popup widget (similar to curses UI)
* proper command-line widget (best would be a Scintilla view, s.a.)
* speed improvements
* STYLE_DEFAULT and STYLE_CALLTIP should be used for styling the
diff --git a/configure.ac b/configure.ac
index 3011c22..a31658b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -229,21 +229,32 @@ case $INTERFACE in
])
AC_DEFINE(INTERFACE_CURSES, , [Build with curses support])
- # For Scintilla:
+ # For Scintilla/Scinterm:
CPPFLAGS="$CPPFLAGS -DCURSES -I$SCINTERM_PATH"
;;
gtk)
- PKG_CHECK_MODULES(LIBGTK, [gtk+-2.0 gmodule-2.0], [
+ # NOTE: Ubuntu 14.04 only has Gtk+ 3.10, so we have to support it.
+ # This version lacks GtkFlowBox.
+ # gmodule is required by Scintilla.
+ PKG_CHECK_MODULES(LIBGTK, [gtk+-3.0 >= 3.10 gmodule-2.0], [
CFLAGS="$CFLAGS $LIBGTK_CFLAGS"
CXXFLAGS="$CXXFLAGS $LIBGTK_CFLAGS"
LIBS="$LIBS $LIBGTK_LIBS"
])
+
+ # Should be available since v3.12
+ AC_CHECK_FUNCS(gtk_flow_box_new, [], [
+ GTK_FLOW_BOX_FALLBACK=true
+ ])
+ AM_CONDITIONAL(GTK_FLOW_BOX_FALLBACK, [test x$GTK_FLOW_BOX_FALLBACK = xtrue])
+
AC_CHECK_PROG(GOB2, gob2, gob2)
if [[ x$GOB2 = x ]]; then
AC_MSG_ERROR([Gob2 (GObject Builder) not found!])
fi
- AC_DEFINE(INTERFACE_GTK, , [Build with GTK+ 2.0 support])
+
+ AC_DEFINE(INTERFACE_GTK, , [Build with GTK+ 3.0 support])
# For Scintilla:
CPPFLAGS="$CPPFLAGS -DGTK"
diff --git a/scintilla.am b/scintilla.am
index 6272af3..df340bf 100644
--- a/scintilla.am
+++ b/scintilla.am
@@ -4,7 +4,7 @@
if INTERFACE_GTK
MAKE_SCINTILLA = $(MAKE) -C @SCINTILLA_PATH@/gtk \
- CONFIGFLAGS='@LIBGTK_CFLAGS@'
+ GTK3=yes CONFIGFLAGS='@LIBGTK_CFLAGS@'
else
MAKE_SCINTILLA = $(MAKE) -C @SCINTERM_PATH@ \
CURSES_FLAGS='@PDCURSES_CFLAGS@ @XCURSES_CFLAGS@ @NCURSES_CFLAGS@'
diff --git a/src/Makefile.am b/src/Makefile.am
index 384d8f3..3c60ba0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -52,9 +52,12 @@ if INTERFACE_GTK
BUILT_SOURCES += gtk-info-popup.c \
gtk-info-popup.h gtk-info-popup-private.h
+nodist_libsciteco_base_a_SOURCES += gtk-info-popup.c
libsciteco_base_a_SOURCES += interface-gtk.cpp interface-gtk.h
-nodist_libsciteco_base_a_SOURCES += gtk-info-popup.c
+if GTK_FLOW_BOX_FALLBACK
+libsciteco_base_a_SOURCES += gtkflowbox.c gtkflowbox.h
+endif
else
# else must be Curses interface
@@ -88,7 +91,7 @@ CLEANFILES = $(BUILT_SOURCES) \
symbols-scintilla.cpp symbols-scilexer.cpp
%.c %.h %-private.h : %.gob
- @GOB2@ $<
+ @GOB2@ --gtk3 $<
symbols-scintilla.cpp : @SCINTILLA_PATH@/include/Scintilla.h \
symbols-extract.tes
diff --git a/src/gtk-info-popup.gob b/src/gtk-info-popup.gob
index 914647a..5082091 100644
--- a/src/gtk-info-popup.gob
+++ b/src/gtk-info-popup.gob
@@ -1,7 +1,18 @@
-requires 2.0.16
+requires 2.0.20
-%privateheader{
-#include <gdk/gdk.h>
+%ctop{
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+
+#include <glib/gprintf.h>
+#include <gio/gio.h>
+
+#ifndef HAVE_GTK_FLOW_BOX_NEW
+#include "gtkflowbox.h"
+#endif
%}
%h{
@@ -14,114 +25,181 @@ enum GTK_INFO_POPUP {
DIRECTORY
} Gtk:Info:Popup:Entry:Type;
-class Gtk:Info:Popup from Gtk:Window {
- private GtkWidget *parent;
+class Gtk:Info:Popup from Gtk:Event:Box {
+ public GtkAdjustment *hadjustment;
+ public GtkAdjustment *vadjustment;
+
+ private GtkWidget *flow_box;
init(self)
{
- GtkWidget *vbox;
+ GtkWidget *box, *viewport;
- //gtk_window_set_gravity(GTK_WINDOW(self), GDK_GRAVITY_SOUTH_WEST);
- gtk_container_set_border_width(GTK_CONTAINER(self), 10);
+ /*
+ * A box containing a viewport and scrollbar will
+ * "emulate" a scrolled window.
+ * We cannot use a scrolled window since it ignores
+ * the preferred height of its viewport which breaks
+ * height-for-width management.
+ */
+ box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- vbox = gtk_vbox_new(FALSE, 5);
- gtk_container_set_resize_mode(GTK_CONTAINER(vbox), GTK_RESIZE_PARENT);
- gtk_container_add(GTK_CONTAINER(self), vbox);
- gtk_widget_show(vbox);
- }
+ self->hadjustment = gtk_adjustment_new(0, 0, 0, 0, 0, 0);
+ self->vadjustment = gtk_adjustment_new(0, 0, 0, 0, 0, 0);
- public GtkWidget *
- new(Gtk:Widget *parent)
- {
- Self *widget;
- GtkWidget *toplevel;
+ GtkWidget *scrollbar = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL,
+ self->vadjustment);
- widget = GET_NEW_VARG("type", GTK_WINDOW_POPUP, NULL);
- widget->_priv->parent = parent;
+ self->_priv->flow_box = gtk_flow_box_new();
+ /* take as little height as necessary */
+ gtk_orientable_set_orientation(GTK_ORIENTABLE(self->_priv->flow_box),
+ GTK_ORIENTATION_HORIZONTAL);
+ //gtk_flow_box_set_homogeneous(GTK_FLOW_BOX(self->_priv->flow_box), TRUE);
+ /* this for focus handling only, not for scrolling */
+ gtk_flow_box_set_hadjustment(GTK_FLOW_BOX(self->_priv->flow_box),
+ self->hadjustment);
+ gtk_flow_box_set_vadjustment(GTK_FLOW_BOX(self->_priv->flow_box),
+ self->vadjustment);
- g_signal_connect(parent, "size-allocate",
- G_CALLBACK(self_size_allocate_cb), widget);
- toplevel = gtk_widget_get_toplevel(parent);
- g_signal_connect(toplevel, "configure-event",
- G_CALLBACK(self_configure_cb), widget);
+ gtk_container_set_border_width(GTK_CONTAINER(self->_priv->flow_box), 10);
- return GTK_WIDGET(widget);
+ viewport = gtk_viewport_new(self->hadjustment, self->vadjustment);
+ gtk_container_add(GTK_CONTAINER(viewport), self->_priv->flow_box);
+
+ gtk_box_pack_start(GTK_BOX(box), viewport, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(box), scrollbar, FALSE, FALSE, 0);
+ gtk_widget_show_all(box);
+
+ /*
+ * The top-level widget is a GtkEventBox, so it can have
+ * a background. We assign a default color since the popup
+ * will usually be put in an overlay and we don't want it
+ * to be transparent.
+ * It can also be styled with rounded corners etc.
+ * FIXME: This method of setting a background color is
+ * deprecated. We are supposed to use CSS style providers...
+ */
+ gtk_container_add(GTK_CONTAINER(self), box);
+ GdkRGBA color = {0.5, 0.5, 0.5, 1.0};
+ gtk_widget_override_background_color(GTK_WIDGET(self), GTK_STATE_FLAG_NORMAL,
+ &color);
}
- private void
- position(self)
- {
- GdkWindow *window = gtk_widget_get_window(self->_priv->parent);
- gint x, y;
- gint w, h;
+ override (Gtk:Widget) void
+ size_allocate(Gtk:Widget *widget,
+ Gtk:Allocation *allocation)
+ {
+ GtkWidget *parent = gtk_widget_get_parent(widget);
+ GtkAllocation parent_alloc;
- if (!window)
- return;
- gdk_window_get_origin(window, &x, &y);
- gtk_window_get_size(GTK_WINDOW(self), &w, &h);
+ /*
+ * Adjust the allocation of the popup to be within the
+ * bounds of its parent widget which GtkOvelay does
+ * not seem to do automatically.
+ * Also Gtk does not seem to query this widget's
+ * preferred height.
+ * FIXME: Only works if the GtkInfoPopup is added
+ * directly to the GtkOverlay.
+ */
+ gtk_widget_get_allocation(parent, &parent_alloc);
+ allocation->width = MIN(allocation->width, parent_alloc.width);
+ if (allocation->height > parent_alloc.height) {
+ allocation->y += allocation->height - parent_alloc.height;
+ allocation->height = parent_alloc.height;
+ }
- gtk_window_move(GTK_WINDOW(self), x, y - h);
+ /*
+ * Allocate the adjusted/clipped allocation
+ */
+ PARENT_HANDLER(widget, allocation);
}
- private void
- size_allocate_cb(Gtk:Widget *parent,
- Gtk:Allocation *alloc, gpointer user_data)
+ /*
+ * Adapted from GtkScrolledWindow's gtk_scrolled_window_scroll_event()
+ * since the viewport does not react to scroll events.
+ * FIXME: May need to handle non-delta scrolling, i.e. GDK_SCROLL_UP
+ * and GDK_SCROLL_DOWN.
+ */
+ override (Gtk:Widget) gboolean
+ scroll_event(Gtk:Widget *widget, GdkEventScroll *event)
{
- self_position(SELF(user_data));
- }
+ Self *self = GTK_INFO_POPUP(widget);
+ gdouble delta_x, delta_y;
+
+ if (gdk_event_get_scroll_deltas((GdkEvent *)event,
+ &delta_x, &delta_y)) {
+ GtkAdjustment *adj = self->vadjustment;
+ gdouble page_size = gtk_adjustment_get_page_size(adj);
+ gdouble scroll_unit = pow(page_size, 2.0 / 3.0);
+ gdouble new_value;
+
+ new_value = CLAMP(gtk_adjustment_get_value(adj) + delta_y * scroll_unit,
+ gtk_adjustment_get_lower(adj),
+ gtk_adjustment_get_upper(adj) -
+ gtk_adjustment_get_page_size(adj));
+
+ gtk_adjustment_set_value(adj, new_value);
+
+ return TRUE;
+ }
- private gboolean
- configure_cb(Gtk:Widget *toplevel,
- Gdk:Event:Configure *event, gpointer user_data)
- {
- self_position(SELF(user_data));
return FALSE;
}
- override (Gtk:Widget) void
- show(Gtk:Widget *self)
+ public GtkWidget *
+ new(void)
{
- GtkRequisition req;
+ Self *widget = GET_NEW;
+ return GTK_WIDGET(widget);
+ }
- gtk_widget_size_request(self, &req);
- gtk_window_resize(GTK_WINDOW(self), req.width, req.height);
- self_position(SELF(self));
+ private GIcon *
+ get_icon_for_path(const gchar *path, const gchar *fallback_name)
+ {
+ GFile *file;
+ GFileInfo *info;
+ GIcon *icon = NULL;
+
+ file = g_file_new_for_path(path);
+ info = g_file_query_info(file, "standard::icon", 0, NULL, NULL);
+ if (info) {
+ icon = g_file_info_get_icon(info);
+ g_object_ref(icon);
+ g_object_unref(info);
+ } else {
+ /* fall back to standard icon, but this can still return NULL! */
+ icon = g_icon_new_for_string(fallback_name, NULL);
+ }
+ g_object_unref(file);
- PARENT_HANDLER(self);
+ return icon;
}
public void
add(self, Gtk:Info:Popup:Entry:Type type,
const gchar *name, gboolean highlight)
{
- static const gchar *type2stock[] = {
- [GTK_INFO_POPUP_PLAIN] = NULL,
- [GTK_INFO_POPUP_FILE] = GTK_STOCK_FILE,
- [GTK_INFO_POPUP_DIRECTORY] = GTK_STOCK_DIRECTORY
- };
-
- GtkWidget *vbox = gtk_bin_get_child(GTK_BIN(self));
- GdkScreen *screen = gtk_window_get_screen(GTK_WINDOW(self));
- GtkRequisition req;
-
GtkWidget *hbox;
GtkWidget *label;
gchar *markup;
- gtk_widget_size_request(GTK_WIDGET(self), &req);
- if (req.height > gdk_screen_get_height(screen))
- return;
+ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- hbox = gtk_hbox_new(FALSE, 5);
+ if (type == GTK_INFO_POPUP_FILE || type == GTK_INFO_POPUP_DIRECTORY) {
+ const gchar *fallback = type == GTK_INFO_POPUP_FILE ? "text-x-generic"
+ : "folder";
+ GIcon *icon;
- if (type2stock[type]) {
- GtkWidget *image;
+ icon = self_get_icon_for_path(name, fallback);
+ if (icon) {
+ GtkWidget *image;
- image = gtk_image_new_from_stock(type2stock[type],
- GTK_ICON_SIZE_MENU);
- gtk_box_pack_start(GTK_BOX(hbox), image,
- FALSE, FALSE, 0);
+ image = gtk_image_new_from_gicon(icon, GTK_ICON_SIZE_MENU);
+ g_object_unref(icon);
+ gtk_box_pack_start(GTK_BOX(hbox), image,
+ FALSE, FALSE, 0);
+ }
}
/*
@@ -137,25 +215,51 @@ class Gtk:Info:Popup from Gtk:Window {
gtk_misc_set_alignment(GTK_MISC(label), 0., 0.5);
gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show_all(hbox);
+ gtk_container_add(GTK_CONTAINER(self->_priv->flow_box), hbox);
+ }
- gtk_widget_size_request(GTK_WIDGET(self), &req);
- if (req.height > gdk_screen_get_height(screen)) {
- label = gtk_label_new("...");
- gtk_box_pack_start(GTK_BOX(vbox), label,
- FALSE, FALSE, 0);
- gtk_widget_show(label);
+ public void
+ scroll_page(self)
+ {
+ GtkAdjustment *adj = self->vadjustment;
+ gdouble new_value;
+
+ if (gtk_adjustment_get_value(adj) + gtk_adjustment_get_page_size(adj) ==
+ gtk_adjustment_get_upper(adj)) {
+ /* wrap and scroll back to the top */
+ new_value = gtk_adjustment_get_lower(adj);
+ } else {
+ /* scroll one page */
+ GList *child_list;
+
+ new_value = gtk_adjustment_get_value(adj) +
+ gtk_adjustment_get_page_size(adj);
+
+ /*
+ * Adjust this so only complete entries are shown.
+ * Effectively, this rounds down to the line height.
+ */
+ child_list = gtk_container_get_children(GTK_CONTAINER(self->_priv->flow_box));
+ if (child_list) {
+ new_value -= (gint)new_value %
+ gtk_widget_get_allocated_height(GTK_WIDGET(child_list->data));
+ g_list_free(child_list);
+ }
+
+ /* clip to the maximum possible value */
+ new_value = MIN(new_value, gtk_adjustment_get_upper(adj));
}
+
+ gtk_adjustment_set_value(adj, new_value);
}
public void
clear(self)
{
- GtkWidget *vbox = gtk_bin_get_child(GTK_BIN(self));
GList *children;
- children = gtk_container_get_children(GTK_CONTAINER(vbox));
+ children = gtk_container_get_children(GTK_CONTAINER(self->_priv->flow_box));
for (GList *cur = g_list_first(children);
cur != NULL;
cur = g_list_next(cur))
diff --git a/src/interface-gtk.cpp b/src/interface-gtk.cpp
index 9cfa0b0..9b0b0aa 100644
--- a/src/interface-gtk.cpp
+++ b/src/interface-gtk.cpp
@@ -26,9 +26,16 @@
#include <glib.h>
#include <glib/gprintf.h>
+/*
+ * FIXME: Because of gdk_threads_enter().
+ * The only way to do it in Gtk3 style would be using
+ * idle callbacks into the main thread and sync barriers (inefficient!)
+ * or doing it single-threaded and ticking the Gtk main loop
+ * (may be inefficient since gtk_events_pending() is doing
+ * syscalls; however that may be ailed by doing it less frequently).
+ */
+#define GDK_DISABLE_DEPRECATION_WARNINGS
#include <gdk/gdk.h>
-#include <gdk/gdkkeysyms.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtk.h>
#include "gtk-info-popup.h"
@@ -91,7 +98,7 @@ ViewGtk::initialize_impl(void)
scintilla_set_id(sci, 0);
- gtk_widget_set_usize(get_widget(), 500, 300);
+ gtk_widget_set_size_request(get_widget(), 500, 300);
/*
* This disables mouse and key events on this view.
@@ -124,6 +131,7 @@ void
InterfaceGtk::main_impl(int &argc, char **&argv)
{
static const Cmdline empty_cmdline;
+ GtkWidget *overlay_widget;
GtkWidget *info_content;
/*
@@ -159,9 +167,11 @@ InterfaceGtk::main_impl(int &argc, char **&argv)
* enabling and disabling GDK updates and in order to filter
* mouse and keyboard events going to Scintilla.
*/
+ overlay_widget = gtk_overlay_new();
event_box_widget = gtk_event_box_new();
gtk_event_box_set_above_child(GTK_EVENT_BOX(event_box_widget), TRUE);
- gtk_box_pack_start(GTK_BOX(vbox), event_box_widget, TRUE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(overlay_widget), event_box_widget);
+ gtk_box_pack_start(GTK_BOX(vbox), overlay_widget, TRUE, TRUE, 0);
info_widget = gtk_info_bar_new();
info_content = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_widget));
@@ -180,7 +190,15 @@ InterfaceGtk::main_impl(int &argc, char **&argv)
gtk_container_add(GTK_CONTAINER(window), vbox);
- popup_widget = gtk_info_popup_new(cmdline_widget);
+ /*
+ * Popup widget will be shown in the bottom
+ * of the overlay widget (i.e. the Scintilla views),
+ * filling the entire width.
+ */
+ popup_widget = gtk_info_popup_new();
+ gtk_widget_set_halign(popup_widget, GTK_ALIGN_FILL);
+ gtk_widget_set_valign(popup_widget, GTK_ALIGN_END);
+ gtk_overlay_add_overlay(GTK_OVERLAY(overlay_widget), popup_widget);
gtk_widget_grab_focus(cmdline_widget);
@@ -345,6 +363,19 @@ InterfaceGtk::popup_add_impl(PopupEntryType type,
}
void
+InterfaceGtk::popup_show_impl(void)
+{
+ gdk_threads_enter();
+
+ if (gtk_widget_get_visible(popup_widget))
+ gtk_info_popup_scroll_page(GTK_INFO_POPUP(popup_widget));
+ else
+ gtk_widget_show(popup_widget);
+
+ gdk_threads_leave();
+}
+
+void
InterfaceGtk::popup_clear_impl(void)
{
gdk_threads_enter();
@@ -370,20 +401,19 @@ InterfaceGtk::widget_set_font(GtkWidget *widget, const gchar *font_name)
void
InterfaceGtk::event_loop_impl(void)
{
- GdkPixbuf *icon;
GThread *thread;
/*
* Assign an icon to the window.
* If the file could not be found, we fail silently.
- * On Windows, it may be better to load the icon compiled
+ * FIXME: On Windows, it may be better to load the icon compiled
* as a resource into the binary.
+ * FIXME: Provide all the different icon sizes we have
+ * (gtk_window_set_default_icon_list()).
*/
- icon = gdk_pixbuf_new_from_file(SCITECODATADIR G_DIR_SEPARATOR_S
- "sciteco-48.png",
- NULL);
- if (icon)
- gtk_window_set_icon(GTK_WINDOW(window), icon);
+ gtk_window_set_default_icon_from_file(SCITECODATADIR G_DIR_SEPARATOR_S
+ "sciteco-48.png",
+ NULL);
/*
* When changing views, the new widget is not
@@ -404,6 +434,8 @@ InterfaceGtk::event_loop_impl(void)
gtk_window_set_title(GTK_WINDOW(window), info_current);
gtk_widget_show_all(window);
+ /* don't show popup by default */
+ gtk_widget_hide(popup_widget);
/*
* SIGTERM emulates the "Close" key just like when
@@ -505,16 +537,16 @@ InterfaceGtk::handle_key_press(bool is_shift, bool is_ctl, guint keyval)
gdk_threads_leave();
switch (keyval) {
- case GDK_Escape:
+ case GDK_KEY_Escape:
cmdline.keypress(CTL_KEY_ESC);
break;
- case GDK_BackSpace:
+ case GDK_KEY_BackSpace:
cmdline.keypress(CTL_KEY('H'));
break;
- case GDK_Tab:
+ case GDK_KEY_Tab:
cmdline.keypress('\t');
break;
- case GDK_Return:
+ case GDK_KEY_Return:
cmdline.keypress('\n');
break;
@@ -522,19 +554,19 @@ InterfaceGtk::handle_key_press(bool is_shift, bool is_ctl, guint keyval)
* Function key macros
*/
#define FN(KEY, MACRO) \
- case GDK_##KEY: cmdline.fnmacro(#MACRO); break
+ case GDK_KEY_##KEY: cmdline.fnmacro(#MACRO); break
#define FNS(KEY, MACRO) \
- case GDK_##KEY: cmdline.fnmacro(is_shift ? "S" #MACRO : #MACRO); break
+ case GDK_KEY_##KEY: cmdline.fnmacro(is_shift ? "S" #MACRO : #MACRO); break
FN(Down, DOWN); FN(Up, UP);
FNS(Left, LEFT); FNS(Right, RIGHT);
FN(KP_Down, DOWN); FN(KP_Up, UP);
FNS(KP_Left, LEFT); FNS(KP_Right, RIGHT);
FNS(Home, HOME);
- case GDK_F1...GDK_F35: {
+ case GDK_KEY_F1...GDK_KEY_F35: {
gchar macro_name[3+1];
g_snprintf(macro_name, sizeof(macro_name),
- "F%d", keyval - GDK_F1 + 1);
+ "F%d", keyval - GDK_KEY_F1 + 1);
cmdline.fnmacro(macro_name);
break;
}
@@ -653,7 +685,7 @@ cmdline_key_pressed_cb(GtkWidget *widget, GdkEventKey *event,
g_async_queue_lock(event_queue);
if (g_async_queue_length_unlocked(event_queue) >= 0 &&
- is_ctl && gdk_keyval_to_upper(event->keyval) == GDK_C) {
+ is_ctl && gdk_keyval_to_upper(event->keyval) == GDK_KEY_C) {
/*
* Handle asynchronous interruptions if CTRL+C is pressed.
* This will usually send SIGINT to the entire process
@@ -694,7 +726,7 @@ window_delete_cb(GtkWidget *w, GdkEventAny *e, gpointer user_data)
*/
close_event = (GdkEventKey *)gdk_event_new(GDK_KEY_PRESS);
close_event->window = gtk_widget_get_parent_window(w);
- close_event->keyval = GDK_Close;
+ close_event->keyval = GDK_KEY_Close;
g_async_queue_push(event_queue, close_event);
@@ -717,7 +749,7 @@ sigterm_handler(gpointer user_data)
* Similar to window deletion - emulate "close" key press.
*/
close_event = (GdkEventKey *)gdk_event_new(GDK_KEY_PRESS);
- close_event->keyval = GDK_Close;
+ close_event->keyval = GDK_KEY_Close;
g_async_queue_push(event_queue, close_event);
diff --git a/src/interface-gtk.h b/src/interface-gtk.h
index c10bdd6..b5200ea 100644
--- a/src/interface-gtk.h
+++ b/src/interface-gtk.h
@@ -22,6 +22,8 @@
#include <glib.h>
+/* FIXME: see interface-gtk.cpp */
+#define GDK_DISABLE_DEPRECATION_WARNINGS
#include <gdk/gdk.h>
#include <gtk/gtk.h>
@@ -132,14 +134,8 @@ public:
void popup_add_impl(PopupEntryType type,
const gchar *name, bool highlight = false);
/* implementation of Interface::popup_show() */
- inline void
- popup_show_impl(void)
- {
- /* FIXME: scroll through popup contents */
- gdk_threads_enter();
- gtk_widget_show(popup_widget);
- gdk_threads_leave();
- }
+ void popup_show_impl(void);
+
/* implementation of Interface::popup_is_shown() */
inline bool
popup_is_shown_impl(void)