From: Jim Evins Date: Thu, 3 Dec 2009 04:04:09 +0000 (-0500) Subject: Don't intercept copy/paste operations intended for other widgets X-Git-Tag: glabels-2_3_0~124 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=2d0b321b49e0dcf8701d000bc2c5f9f4673689f8;p=glabels Don't intercept copy/paste operations intended for other widgets Fixes bugs 1683799, 2833194 and probably 1978142. Only enable copy/paste verbs if the focused widget is the glView. Otherwise let these operations propagate to the focused widget to be handled natively. --- diff --git a/.gitignore b/.gitignore index b89e7e48..bbfdd154 100644 --- a/.gitignore +++ b/.gitignore @@ -80,6 +80,8 @@ glabels-*.tar.gz # *~ *.bak +\#*\# +.\#* .*.swp *.orig *.rej diff --git a/src/label.c b/src/label.c index b3616855..770ecbcf 100644 --- a/src/label.c +++ b/src/label.c @@ -38,8 +38,6 @@ /* Private macros and constants. */ /*========================================================*/ -#define GLABELS_CLIPBOARD gdk_atom_intern ("GLABELS", FALSE) - /*========================================================*/ /* Private types. */ @@ -2164,14 +2162,14 @@ gl_label_set_selection_line_width (glLabel *label, /*****************************************************************************/ void gl_label_cut_selection (glLabel *label, - GtkWidget *owner) + GtkClipboard *glabels_clipboard, + GtkClipboard *std_clipboard) { gl_debug (DEBUG_LABEL, "START"); g_return_if_fail (label && GL_IS_LABEL (label)); - g_return_if_fail (owner && GTK_IS_WIDGET (owner)); - gl_label_copy_selection (label, owner); + gl_label_copy_selection (label, glabels_clipboard, std_clipboard); gl_label_delete_selection (label); gl_debug (DEBUG_LABEL, "END"); @@ -2183,10 +2181,10 @@ gl_label_cut_selection (glLabel *label, /*****************************************************************************/ void gl_label_copy_selection (glLabel *label, - GtkWidget *owner) + GtkClipboard *glabels_clipboard, + GtkClipboard *std_clipboard) { GList *selection_list; - GtkClipboard *clipboard; glLabel *label_copy; GList *p; glLabelObject *object; @@ -2197,13 +2195,11 @@ gl_label_copy_selection (glLabel *label, gl_debug (DEBUG_LABEL, "START"); g_return_if_fail (label && GL_IS_LABEL (label)); - g_return_if_fail (owner && GTK_IS_WIDGET (owner)); selection_list = gl_label_get_selection_list (label); if (selection_list) { - clipboard = gtk_widget_get_clipboard (owner, GLABELS_CLIPBOARD); label_copy = GL_LABEL(gl_label_new ()); gl_label_set_template (label_copy, label->priv->template); @@ -2218,7 +2214,7 @@ gl_label_copy_selection (glLabel *label, buffer = gl_xml_label_save_buffer (label_copy, &status); - gtk_clipboard_set_text (clipboard, buffer, -1); + gtk_clipboard_set_text (glabels_clipboard, buffer, -1); g_free (buffer); g_object_unref (G_OBJECT (label_copy)); @@ -2231,11 +2227,9 @@ gl_label_copy_selection (glLabel *label, */ if ( gl_label_is_selection_atomic (label) ) { - clipboard = gtk_widget_get_clipboard (owner, GDK_SELECTION_CLIPBOARD); - object = GL_LABEL_OBJECT (selection_list->data); - gl_label_object_copy_to_clipboard (object, clipboard); + gl_label_object_copy_to_clipboard (object, std_clipboard); } g_list_free (selection_list); @@ -2249,18 +2243,14 @@ gl_label_copy_selection (glLabel *label, /*****************************************************************************/ void gl_label_paste (glLabel *label, - GtkWidget *owner) + GtkClipboard *glabels_clipboard, + GtkClipboard *std_clipboard) { - GtkClipboard *clipboard; - gl_debug (DEBUG_LABEL, "START"); g_return_if_fail (label && GL_IS_LABEL (label)); - g_return_if_fail (owner && GTK_IS_WIDGET (owner)); - - clipboard = gtk_widget_get_clipboard (owner, GLABELS_CLIPBOARD); - gtk_clipboard_request_text (clipboard, + gtk_clipboard_request_text (glabels_clipboard, (GtkClipboardTextReceivedFunc)paste_received_cb, label); diff --git a/src/label.h b/src/label.h index 0eb73cdf..35b86c47 100644 --- a/src/label.h +++ b/src/label.h @@ -253,13 +253,16 @@ void gl_label_set_selection_line_width (glLabel *label, * Clipboard operations */ void gl_label_cut_selection (glLabel *label, - GtkWidget *owner); + GtkClipboard *glabels_clipboard, + GtkClipboard *std_clipboard); void gl_label_copy_selection (glLabel *label, - GtkWidget *owner); + GtkClipboard *glabels_clipboard, + GtkClipboard *std_clipboard); void gl_label_paste (glLabel *label, - GtkWidget *owner); + GtkClipboard *glabels_clipboard, + GtkClipboard *std_clipboard); /* diff --git a/src/ui-commands.c b/src/ui-commands.c index d87f9a5a..28db9653 100644 --- a/src/ui-commands.c +++ b/src/ui-commands.c @@ -25,6 +25,7 @@ #include #include +#include "ui.h" #include "view.h" #include "file.h" #include "template-designer.h" @@ -257,14 +258,21 @@ void gl_ui_cmd_edit_cut (GtkAction *action, glWindow *window) { + GtkClipboard *glabels_clipboard; + GtkClipboard *std_clipboard; + gl_debug (DEBUG_COMMANDS, "START"); g_return_if_fail (action && GTK_IS_ACTION(action)); g_return_if_fail (window && GL_IS_WINDOW(window)); - gl_label_cut_selection (GL_VIEW(window->view)->label, - GTK_WIDGET (window)); + glabels_clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), + GL_UI_GLABELS_CLIPBOARD); + + std_clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), + GDK_SELECTION_CLIPBOARD); + gl_label_cut_selection (window->label, glabels_clipboard, std_clipboard); gl_debug (DEBUG_COMMANDS, "END"); } @@ -277,15 +285,21 @@ void gl_ui_cmd_edit_copy (GtkAction *action, glWindow *window) { - GtkClipboard *clipboard; + GtkClipboard *glabels_clipboard; + GtkClipboard *std_clipboard; gl_debug (DEBUG_COMMANDS, "START"); g_return_if_fail (action && GTK_IS_ACTION(action)); g_return_if_fail (window && GL_IS_WINDOW(window)); - gl_label_copy_selection (GL_VIEW(window->view)->label, - GTK_WIDGET (window)); + glabels_clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), + GL_UI_GLABELS_CLIPBOARD); + + std_clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), + GDK_SELECTION_CLIPBOARD); + + gl_label_copy_selection (window->label, glabels_clipboard, std_clipboard); gl_debug (DEBUG_COMMANDS, "END"); } @@ -298,15 +312,21 @@ void gl_ui_cmd_edit_paste (GtkAction *action, glWindow *window) { - GtkClipboard *clipboard; + GtkClipboard *glabels_clipboard; + GtkClipboard *std_clipboard; gl_debug (DEBUG_COMMANDS, "START"); g_return_if_fail (action && GTK_IS_ACTION(action)); g_return_if_fail (window && GL_IS_WINDOW(window)); - gl_label_paste (GL_VIEW(window->view)->label, - GTK_WIDGET (window)); + glabels_clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), + GL_UI_GLABELS_CLIPBOARD); + + std_clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), + GDK_SELECTION_CLIPBOARD); + + gl_label_paste (window->label, glabels_clipboard, std_clipboard); gl_debug (DEBUG_COMMANDS, "END"); } diff --git a/src/ui.c b/src/ui.c index 34b1121d..ae190dcc 100644 --- a/src/ui.c +++ b/src/ui.c @@ -866,15 +866,25 @@ gl_ui_update_selection_verbs (GtkUIManager *ui, { gl_debug (DEBUG_UI, "START"); - gl_ui_util_set_verb_list_sensitive (ui, selection_verbs, - !gl_label_is_selection_empty (view->label)); - - gl_ui_util_set_verb_list_sensitive (ui, atomic_selection_verbs, - gl_label_is_selection_atomic (view->label)); - - gl_ui_util_set_verb_list_sensitive (ui, multi_selection_verbs, - !gl_label_is_selection_empty (view->label) - && !gl_label_is_selection_atomic (view->label)); + if ( gtk_widget_has_focus (GTK_WIDGET (view->canvas)) ) + { + + gl_ui_util_set_verb_list_sensitive (ui, selection_verbs, + !gl_label_is_selection_empty (view->label)); + + gl_ui_util_set_verb_list_sensitive (ui, atomic_selection_verbs, + gl_label_is_selection_atomic (view->label)); + + gl_ui_util_set_verb_list_sensitive (ui, multi_selection_verbs, + !gl_label_is_selection_empty (view->label) + && !gl_label_is_selection_atomic (view->label)); + } + else + { + gl_ui_util_set_verb_list_sensitive (ui, selection_verbs, FALSE); + gl_ui_util_set_verb_list_sensitive (ui, atomic_selection_verbs, FALSE); + gl_ui_util_set_verb_list_sensitive (ui, multi_selection_verbs, FALSE); + } gl_debug (DEBUG_UI, "END"); } diff --git a/src/ui.h b/src/ui.h index 158daaf0..81f36673 100644 --- a/src/ui.h +++ b/src/ui.h @@ -28,6 +28,10 @@ G_BEGIN_DECLS + +#define GL_UI_GLABELS_CLIPBOARD gdk_atom_intern ("GLABELS", FALSE) + + GtkUIManager *gl_ui_new (glWindow *window); void gl_ui_unref (GtkUIManager *ui); diff --git a/src/window.c b/src/window.c index 4206dda6..7a7f7a66 100644 --- a/src/window.c +++ b/src/window.c @@ -46,8 +46,6 @@ #define CURSOR_INFO_WIDTH 150 #define ZOOM_INFO_WIDTH 50 -#define GLABELS_CLIPBOARD gdk_atom_intern ("GLABELS", FALSE) - /*===========================================================================*/ /* Private globals */ @@ -100,6 +98,13 @@ static void clipboard_changed_cb (GtkClipboard *clipboard, GdkEvent *event, glWindow *window); +static void focus_widget_changed_cb(GtkWindow *gtk_window, + GtkWidget *widget, + glWindow *window); + +static void set_paste_sensitivity (glWindow *window, + GtkWidget *focus_widget); + /****************************************************************************/ /* Boilerplate Object stuff. */ @@ -226,7 +231,9 @@ gl_window_finalize (GObject *object) static void gl_window_destroy (GtkObject *gtk_object) { - glWindow *window; + glWindow *window; + GtkClipboard *glabels_clipboard; + GtkClipboard *std_clipboard; gl_debug (DEBUG_WINDOW, "START"); @@ -241,6 +248,18 @@ gl_window_destroy (GtkObject *gtk_object) window->ui = NULL; } + if (window->label) + { + glabels_clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), + GL_UI_GLABELS_CLIPBOARD); + + g_signal_handlers_disconnect_by_func (G_OBJECT (glabels_clipboard), + G_CALLBACK (clipboard_changed_cb), + window); + + g_object_unref (window->label); + } + if (GTK_OBJECT_CLASS (gl_window_parent_class)->destroy) { GTK_OBJECT_CLASS (gl_window_parent_class)->destroy (gtk_object); } @@ -340,14 +359,15 @@ gl_window_set_label (glWindow *window, glLabel *label) { gchar *string; - GtkClipboard *clipboard; + GtkClipboard *glabels_clipboard; + GtkWidget *focus_widget; gl_debug (DEBUG_WINDOW, "START"); g_return_if_fail (GL_IS_WINDOW (window)); g_return_if_fail (GL_IS_LABEL (label)); - window->label = label; + window->label = g_object_ref (label); gl_label_clear_modified (label); @@ -387,9 +407,9 @@ gl_window_set_label (glWindow *window, gtk_label_set_text (GTK_LABEL(window->zoom_info), string); g_free (string); - clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), GLABELS_CLIPBOARD); - gl_ui_update_paste_verbs (window->ui, - gtk_clipboard_wait_is_text_available (clipboard)); + + glabels_clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), + GL_UI_GLABELS_CLIPBOARD); g_signal_connect (G_OBJECT(window->label), "selection_changed", @@ -413,9 +433,16 @@ gl_window_set_label (glWindow *window, g_signal_connect (G_OBJECT(label), "modified_changed", G_CALLBACK(modified_changed_cb), window); - g_signal_connect (G_OBJECT(clipboard), "owner_change", + g_signal_connect (G_OBJECT(glabels_clipboard), "owner_change", G_CALLBACK(clipboard_changed_cb), window); + g_signal_connect (G_OBJECT(window), "set_focus", + G_CALLBACK(focus_widget_changed_cb), window); + + /* Initialize "Paste" sensitivity. */ + focus_widget = gtk_window_get_focus (GTK_WINDOW (window)); + set_paste_sensitivity (window, focus_widget); + gl_debug (DEBUG_WINDOW, "END"); } @@ -496,7 +523,7 @@ selection_changed_cb (glLabel *label, g_return_if_fail (label && GL_IS_LABEL (label)); g_return_if_fail (window && GL_IS_WINDOW (window)); - gl_ui_update_selection_verbs (window->ui, GL_VIEW (window->view)); + gl_ui_update_selection_verbs (window->ui, GL_VIEW (window->view)); gl_debug (DEBUG_WINDOW, "END"); } @@ -646,22 +673,81 @@ modified_changed_cb (glLabel *label, } +/*---------------------------------------------------------------------------*/ +/** PRIVATE. Clipboard "owner change" callback. */ +/*---------------------------------------------------------------------------*/ static void clipboard_changed_cb (GtkClipboard *clipboard, GdkEvent *event, glWindow *window) +{ + GtkWidget *focus_widget; + + gl_debug (DEBUG_WINDOW, "START"); + + g_return_if_fail (window && GL_IS_WINDOW (window)); + + focus_widget = gtk_window_get_focus (GTK_WINDOW (window)); + set_paste_sensitivity (window, focus_widget); + + gl_debug (DEBUG_WINDOW, "END"); +} + + +/*---------------------------------------------------------------------------*/ +/** PRIVATE. Window "set-focus" callback. */ +/*---------------------------------------------------------------------------*/ +static void +focus_widget_changed_cb (GtkWindow *gtk_window, + GtkWidget *widget, + glWindow *window) { gl_debug (DEBUG_WINDOW, "START"); g_return_if_fail (window && GL_IS_WINDOW (window)); - gl_ui_update_paste_verbs (window->ui, - gtk_clipboard_wait_is_text_available (clipboard)); + if (widget) + { + gl_debug (DEBUG_WINDOW, "SET-FOCUS %x %s\n", + widget, + G_OBJECT_TYPE_NAME (widget)); + + set_paste_sensitivity (window, widget); + } gl_debug (DEBUG_WINDOW, "END"); } +/*---------------------------------------------------------------------------*/ +/** PRIVATE. Set paste sensitivity. */ +/*---------------------------------------------------------------------------*/ +static void +set_paste_sensitivity (glWindow *window, + GtkWidget *focus_widget) +{ + GtkClipboard *glabels_clipboard; + + gl_debug (DEBUG_WINDOW, "START"); + + g_return_if_fail (window && GL_IS_WINDOW (window)); + + glabels_clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), + GL_UI_GLABELS_CLIPBOARD); + + if ( focus_widget == GL_VIEW(window->view)->canvas ) + { + gl_ui_update_paste_verbs (window->ui, + gtk_clipboard_wait_is_text_available (glabels_clipboard)); + } + else + { + gl_ui_update_paste_verbs (window->ui, FALSE); + } + + gl_debug (DEBUG_WINDOW, "END"); +} + /* * Local Variables: -- emacs