[nautilus/gnome-3-6] editable-label: add an input-only window for events



commit 2ad722fc39a1e4c0219d23cd43893d0f6b78d05b
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]