****** URGENT: gtkprint; new release by November end for Debian!
nb: libgnomeprint produces many warnings (spinbutton; gpa assertions)
+ nb: gtkprint includes sft.c or not?? see font generation...
+- get GTK+ 2.17 events while editing text to work.
- prerelease: update help file (remove references to pdftoppm/libgnomeprint
to poppler/gtkprint
- remove "antialias bg" flag, useless... see McElrath
(need to shift by (sx,sy), + shift between canvas->window vs canvas in 2.17)
- Esc should leave text box if editing; and fullscreen if fullscreen?
- color chooser button (patch tracker?)
+- option to have buttons *toggle* the tool rather than act as tool
+ (ie button 2 causes button 1 to map to tool 2) [Dylan Thurston]
** auto-hide patch from ~/prog/src/xournal-autohide/ ?
(check for cpu usage, add flag if need be; handle BOTH edges
and only (un)hide stuff at the correct edge!)
- more paper customization (in particular, 1/2 inch graph paper)
(2 custom papers with settings in config file?
a folder with blank PDF or xoj papers and quick-access?)
+ (also: engineering paper; isometric paper -- Dan Ott Sep 4 '09)
- option to map a button to a context menu (incl. tool selection, ...)
- option to map a button to "undo"
- xournal_page-shadow.diff (Martin Kiefel Feb 5 2007)
double DEFAULT_ZOOM;
-// prevent interface items from getting bogus XInput events
-gboolean filter_extended_events (GtkWidget *widget, GdkEvent *event,
- gpointer user_data)
-{
- // prevent scrollbars from reacting to XInput events
- if (event->type == GDK_MOTION_NOTIFY &&
- event->motion.device != gdk_device_get_core_pointer())
- return TRUE;
- if ((event->type == GDK_BUTTON_PRESS || event->type == GDK_2BUTTON_PRESS ||
- event->type == GDK_3BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) &&
- event->button.device != gdk_device_get_core_pointer())
- return TRUE;
- return FALSE;
-}
-
void init_stuff (int argc, char *argv[])
{
GtkWidget *w;
g_signal_connect ((gpointer) canvas, "enter_notify_event",
G_CALLBACK (on_canvas_enter_notify_event),
NULL);
+ g_signal_connect ((gpointer) canvas, "leave_notify_event",
+ G_CALLBACK (on_canvas_leave_notify_event),
+ NULL);
g_signal_connect ((gpointer) canvas, "expose_event",
G_CALLBACK (on_canvas_expose_event),
NULL);
gtk_widget_set_sensitive(GET_COMPONENT("optionsUseXInput"), FALSE);
ui.use_xinput = ui.allow_xinput && can_xinput;
+ ui.need_emergency_disable_xinput = FALSE;
gtk_check_menu_item_set_active(
GTK_CHECK_MENU_ITEM(GET_COMPONENT("optionsAntialiasBG")), ui.antialias_bg);
/* fix a bug in GTK+ 2.16 and beyond: scrollbars shouldn't get extended
input events from pointer motion when cursor moves into main window */
#if GTK_CHECK_VERSION(2,14,0)
- if (!gtk_check_version(2, 14, 0)) {
+ if (!gtk_check_version(2, 16, 0)) {
g_signal_connect (
GET_COMPONENT("menubar"),
"event", G_CALLBACK (filter_extended_events),
(gpointer)(gtk_scrolled_window_get_hscrollbar(GTK_SCROLLED_WINDOW(w))),
"event", G_CALLBACK (filter_extended_events),
NULL);
+ g_signal_connect (
+ GET_COMPONENT("comboLayer"),
+ "notify::popup-shown", G_CALLBACK (combobox_popup_disable_xinput),
+ NULL);
}
#endif
#endif
if (!finite(event->x) || !finite(event->y)) return FALSE; // Xorg 7.3 bug
- if (ui.cur_item_type == ITEM_TEXT && !is_event_within_textview(event))
- end_text();
+ if (ui.cur_item_type == ITEM_TEXT) {
+ if (!is_event_within_textview(event)) end_text();
+/* // bugfix for GTK+ 2.17, no longer needed as XInput is disabled during text edition
+ else fix_extended_events(ui.cur_item->widget, (GdkEvent *)event,
+ gtk_text_view_get_window(GTK_TEXT_VIEW(ui.cur_item->widget), GTK_TEXT_WINDOW_TEXT));
+*/
+ }
if (ui.cur_item_type == ITEM_STROKE && ui.is_corestroke && !is_core &&
ui.cur_path.num_points == 1) {
// Xorg 7.3+ sent core event before XInput event: fix initial point
return FALSE;
}
+gboolean
+on_canvas_leave_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event,
+ gpointer user_data)
+{
+#ifdef INPUT_DEBUG
+ printf("DEBUG: leave notify\n");
+#endif
+ if (ui.need_emergency_disable_xinput) {
+ gtk_widget_set_extension_events(GTK_WIDGET (canvas), GDK_EXTENSION_EVENTS_NONE);
+ ui.need_emergency_disable_xinput = FALSE;
+ }
+ return FALSE;
+}
+
gboolean
on_canvas_expose_event (GtkWidget *widget,
ui.allow_xinput = ui.use_xinput =
gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
-/* Important note: we'd like ONLY the canvas window itself to receive
+/* HOW THINGS USED TO BE:
+
+ We'd like ONLY the canvas window itself to receive
XInput events, while its child window in the GDK hierarchy (also
associated to the canvas widget) receives the core events.
This way on_canvas_... will get both types of events -- otherwise,
also traverses GDK child windows that belong to the widget
and sets their extension events too. We want to avoid that.
So we use gdk_input_set_extension_events() directly on the canvas.
+
+ As much as possible, we'd like to keep doing this, though GTK+ 2.17
+ is making our life harder (crasher bugs require us to disable XInput
+ while editing text or using the layers combo box, but disabling
+ XInput while in a XInput-aware window causes the interface to become
+ non-responsive).
*/
-
-/* // this causes GTK+ 2.11 bugs
- gtk_widget_set_extension_events(GTK_WIDGET (canvas),
+
+ // this causes core events to be discarded... unwanted!
+/*
+ gtk_widget_set_extension_events(GTK_WIDGET (canvas),
ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
*/
+
+ // this version only activates extension events on the canvas's parent GdkWindow
gdk_input_set_extension_events(GTK_WIDGET(canvas)->window,
GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK,
ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
GdkEventCrossing *event,
gpointer user_data);
+gboolean
+on_canvas_leave_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event,
+ gpointer user_data);
+
gboolean
on_canvas_expose_event (GtkWidget *widget,
GdkEventExpose *event,
#include <gtk/gtk.h>
#include <libgnomecanvas/libgnomecanvas.h>
#include <gdk/gdkkeysyms.h>
+#include <X11/Xlib.h>
#include "xournal.h"
#include "xo-interface.h"
gtk_widget_hide(GET_COMPONENT("optionsSavePreferences"));
}
}
+
+/* attempt to work around GTK+ 2.16/2.17 bugs where random interface
+ elements receive XInput events that they can't handle properly */
+
+// prevent interface items from getting bogus XInput events
+
+gboolean filter_extended_events (GtkWidget *widget, GdkEvent *event,
+ gpointer user_data)
+{
+ if (event->type == GDK_MOTION_NOTIFY &&
+ event->motion.device != gdk_device_get_core_pointer())
+ return TRUE;
+ if ((event->type == GDK_BUTTON_PRESS || event->type == GDK_2BUTTON_PRESS ||
+ event->type == GDK_3BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) &&
+ event->button.device != gdk_device_get_core_pointer())
+ return TRUE;
+ return FALSE;
+}
+
+/* Code to turn an extended input event into a core event and send it to
+ a different GdkWindow -- e.g. could be used when a click in a text edit box
+ gets sent to the canvas instead due to incorrect event translation.
+ We now turn off xinput altogether while editing text under GTK+ 2.17, so
+ this isn't needed any more... but could become useful again someday!
+*/
+
+/*
+gboolean fix_extended_events (GtkWidget *widget, GdkEvent *event,
+ gpointer user_data)
+{
+ int ix, iy;
+ GdkWindow *window;
+
+ if (user_data) window = (GdkWindow *)user_data;
+ else window = widget->window;
+
+ if (event->type == GDK_MOTION_NOTIFY &&
+ event->motion.device != gdk_device_get_core_pointer()) {
+// printf("fixing motion\n");
+ gdk_window_get_pointer(window, &ix, &iy, NULL);
+ event->motion.x = ix; event->motion.y = iy;
+ event->motion.device = gdk_device_get_core_pointer();
+ g_object_unref(event->motion.window);
+ event->motion.window = g_object_ref(window);
+ gtk_widget_event(widget, event);
+ return TRUE;
+ }
+ if ((event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) &&
+ event->button.device != gdk_device_get_core_pointer()) {
+// printf("fixing button from pos = %f, %f\n", event->button.x, event->button.y);
+ gdk_window_get_pointer(window, &ix, &iy, NULL);
+ event->button.x = ix; event->button.y = iy;
+ event->button.device = gdk_device_get_core_pointer();
+ g_object_unref(event->button.window);
+ event->button.window = g_object_ref(window);
+// printf("fixing button to pos = %f, %f\n", event->button.x, event->button.y);
+ gtk_widget_event(widget, event);
+ return TRUE;
+ }
+ return FALSE;
+}
+*/
+
+// disable xinput when layer combo box is popped up, to avoid crash
+
+gboolean combobox_popup_disable_xinput (GtkWidget *widget, GdkEvent *event,
+ gpointer user_data)
+{
+ gboolean is_shown;
+
+ g_object_get(G_OBJECT(widget), "popup-shown", &is_shown, NULL);
+ gdk_input_set_extension_events(GTK_WIDGET(canvas)->window,
+ GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK,
+ (ui.use_xinput && !is_shown)?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
+}
void hide_unimplemented(void);
+// fix GTK+ 2.16/2.17 issues with XInput events
+gboolean filter_extended_events(GtkWidget *widget, GdkEvent *event, gpointer user_data);
+// gboolean fix_extended_events(GtkWidget *widget, GdkEvent *event, gpointer user_data);
+gboolean combobox_popup_disable_xinput(GtkWidget *widget, GdkEvent *event, gpointer user_data);
+
// defines for paper rulings
#define RULING_MARGIN_COLOR 0xff0080ff
get_pointer_coords(event, pt);
ui.cur_item_type = ITEM_TEXT;
+ // HACK TO BYPASS GTK+ 2.17 issues
+ if (!gtk_check_version(2, 17, 0)) {
+ /* first we make *all* canvas subwindows become XInput aware,
+ so that it'll be safe to disable XInput later on... (!!!) */
+ gtk_widget_set_extension_events(GTK_WIDGET (canvas),
+ ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
+ /* then we ask the canvas's leave-notify handler to disable
+ xinput when it's safe to do so... */
+ ui.need_emergency_disable_xinput = TRUE;
+ }
+
if (item==NULL) {
item = g_new(struct Item, 1);
item->text = NULL;
GnomeCanvasItem *tmpitem;
if (ui.cur_item_type!=ITEM_TEXT) return; // nothing for us to do!
+
+ // HACK TO BYPASS GTK+ 2.17 issues
+ if (!gtk_check_version(2, 17, 0)) {
+ // re-enable XInput if needed (we disabled it during text edition)
+ gdk_input_set_extension_events(GTK_WIDGET(canvas)->window,
+ GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK,
+ ui.use_xinput?GDK_EXTENSION_EVENTS_ALL:GDK_EXTENSION_EVENTS_NONE);
+ }
// finalize the text that's been edited...
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(ui.cur_item->widget));
gboolean shorten_menus; // shorten menus ?
gchar *shorten_menu_items; // which items to hide
gboolean is_sel_cursor; // displaying a selection-related cursor
+ gboolean need_emergency_disable_xinput; // need to disable xinput to avoid GTK+ 2.17 bug ?
} UIData;
#define BRUSH_LINKED 0