[nautilus] editable-label: add an input-only window for events



commit d5c4c3c0f3b12dac24479f5195dafac84cc7a3c1
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Wed Oct 17 23:15:29 2012 -0400

    editable-label: add an input-only window for events
    
    Add another input-only child to the parent GdkWindow's for events and
    imcontext. Since we will be painted in a GtkLayout, using only one
    input-only window won't work well with scrolling, but this way we can
    ensure that whatever GdkWindow the XIM engine will try to ensure native,
    it won't be our (floating) drawing window.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=686053

 eel/eel-editable-label.c |   47 ++++++++++++++++++++++++++++++++++++++++-----
 eel/eel-editable-label.h |    2 +
 2 files changed, 43 insertions(+), 6 deletions(-)
---
diff --git a/eel/eel-editable-label.c b/eel/eel-editable-label.c
index 8a9057b..00df6ab 100644
--- a/eel/eel-editable-label.c
+++ b/eel/eel-editable-label.c
@@ -1172,7 +1172,12 @@ static void
 eel_editable_label_size_allocate (GtkWidget     *widget,
 				  GtkAllocation *allocation)
 {
+  EelEditableLabel *label = EEL_EDITABLE_LABEL (widget);
+
   (* GTK_WIDGET_CLASS (eel_editable_label_parent_class)->size_allocate) (widget, allocation);
+
+  gdk_window_move_resize (label->text_area, allocation->x, allocation->y,
+                          allocation->width, allocation->height);
 }
 
 static void
@@ -1603,7 +1608,6 @@ eel_editable_label_realize (GtkWidget *widget)
   attributes.width = allocation.width;
   attributes.height = allocation.height;
   attributes.visual = gtk_widget_get_visual (widget);
-  attributes.cursor = gdk_cursor_new (GDK_XTERM);
   attributes.event_mask = gtk_widget_get_events (widget) |
     (GDK_EXPOSURE_MASK |
      GDK_BUTTON_PRESS_MASK |
@@ -1615,18 +1619,35 @@ eel_editable_label_realize (GtkWidget *widget)
      GDK_ENTER_NOTIFY_MASK |
      GDK_LEAVE_NOTIFY_MASK);
 
-  attributes_mask = GDK_WA_X | GDK_WA_Y  | GDK_WA_VISUAL | GDK_WA_CURSOR;
+  attributes_mask = GDK_WA_X | GDK_WA_Y  | GDK_WA_VISUAL;
 
   window = gdk_window_new (gtk_widget_get_parent_window (widget),
 			   &attributes, attributes_mask);
   gtk_widget_set_window (widget, window);
   gdk_window_set_user_data (window, widget);
 
+  attributes.cursor = gdk_cursor_new (GDK_XTERM);
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.wclass = GDK_INPUT_ONLY;
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
+                            GDK_BUTTON_RELEASE_MASK |
+                            GDK_BUTTON1_MOTION_MASK |
+                            GDK_BUTTON3_MOTION_MASK |
+                            GDK_POINTER_MOTION_HINT_MASK |
+                            GDK_POINTER_MOTION_MASK |
+                            GDK_ENTER_NOTIFY_MASK |
+                            GDK_LEAVE_NOTIFY_MASK);
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_CURSOR;
+
+  label->text_area = gdk_window_new (gtk_widget_get_parent_window (widget),
+                                     &attributes, attributes_mask);
+  gdk_window_set_user_data (label->text_area, widget);
+  gtk_im_context_set_client_window (label->im_context, label->text_area);
   g_object_unref (attributes.cursor);
 
   style = gtk_widget_get_style_context (widget);
   gtk_style_context_set_background (style, gtk_widget_get_window (widget));
-  gtk_im_context_set_client_window (label->im_context, gtk_widget_get_window (widget));
 }
 
 static void
@@ -1636,8 +1657,14 @@ eel_editable_label_unrealize (GtkWidget *widget)
 
   label = EEL_EDITABLE_LABEL (widget);
 
-  /* Strange. Copied from GtkEntry, should be NULL? */
   gtk_im_context_set_client_window (label->im_context, NULL);
+
+  if (label->text_area)
+    {
+      gdk_window_set_user_data (label->text_area, NULL);
+      gdk_window_destroy (label->text_area);
+      label->text_area = NULL;
+    }
   
   (* GTK_WIDGET_CLASS (eel_editable_label_parent_class)->unrealize) (widget);
 }
@@ -1645,12 +1672,20 @@ eel_editable_label_unrealize (GtkWidget *widget)
 static void
 eel_editable_label_map (GtkWidget *widget)
 {
+  EelEditableLabel *label = EEL_EDITABLE_LABEL (widget);
+
   (* GTK_WIDGET_CLASS (eel_editable_label_parent_class)->map) (widget);
+
+  gdk_window_show (label->text_area);
 }
 
 static void
 eel_editable_label_unmap (GtkWidget *widget)
 {
+  EelEditableLabel *label = EEL_EDITABLE_LABEL (widget);
+
+  gdk_window_hide (label->text_area);
+
   (* GTK_WIDGET_CLASS (eel_editable_label_parent_class)->unmap) (widget);
 }
 
@@ -1848,7 +1883,7 @@ eel_editable_label_motion (GtkWidget      *widget,
   if ((event->state & GDK_BUTTON1_MASK) == 0)
     return FALSE;
 
-  gdk_window_get_device_position (gtk_widget_get_window (widget),
+  gdk_window_get_device_position (label->text_area,
                                   event->device,
                                   &x, &y, NULL);
 
@@ -2984,7 +3019,7 @@ popup_position_func (GtkMenu   *menu,
 
   g_assert (gtk_widget_get_realized (widget));
 
-  gdk_window_get_origin (gtk_widget_get_window (widget), x, y);
+  gdk_window_get_origin (label->text_area, x, y);
 
   /*gtk_widget_size_request (label->popup_menu, &req);*/
   gtk_widget_get_requisition (widget, &req);
diff --git a/eel/eel-editable-label.h b/eel/eel-editable-label.h
index cabcd63..90bf31c 100644
--- a/eel/eel-editable-label.h
+++ b/eel/eel-editable-label.h
@@ -61,6 +61,8 @@ struct _EelEditableLabel
   guint   overwrite_mode : 1;
   guint   draw_outline : 1;
   PangoWrapMode  wrap_mode;
+
+  GdkWindow *text_area;
   
   gchar  *text;
   int text_size; /* allocated size, in bytes */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]