[gtk+/client-side-decorations] basic right-click menu support



commit 28945c7ded7d3f000b3a7e57d2ee738716afff14
Author: Cody Russell <bratsche gnome org>
Date:   Tue Jul 14 20:55:33 2009 -0500

    basic right-click menu support

 gtk/gtkwindow.c |  128 +++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 106 insertions(+), 22 deletions(-)
---
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 24c4309..b923017 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -47,6 +47,7 @@
 #include "gtkmnemonichash.h"
 #include "gtkiconfactory.h"
 #include "gtkicontheme.h"
+#include "gtkimagemenuitem.h"
 #include "gtkmarshalers.h"
 #include "gtkplug.h"
 #include "gtkbuildable.h"
@@ -224,6 +225,8 @@ struct _GtkWindowPrivate
   GtkWidget *close_button;
   GtkWidget *button_box;
   gint cursor_region;
+
+  GtkWidget *popup_menu;
 };
 
 static void gtk_window_dispose            (GObject           *object);
@@ -338,8 +341,10 @@ static void	   gtk_window_on_composited_changed (GdkScreen *screen,
 static void        gtk_window_set_label_widget (GtkWindow *window,
                                                 GtkWidget *label);
 
-static gboolean    is_client_side_decorated    (GtkWindow *window);
-
+static gboolean    is_client_side_decorated    (GtkWindow      *window);
+static gboolean    gtk_window_popup_menu       (GtkWidget      *widget);
+static void        gtk_window_do_popup         (GtkWindow      *window,
+                                                GdkEventButton *event);
 
 static GSList      *toplevel_list = NULL;
 static guint        window_signals[LAST_SIGNAL] = { 0 };
@@ -510,6 +515,7 @@ gtk_window_class_init (GtkWindowClass *klass)
   widget_class->focus = gtk_window_focus;
   widget_class->button_press_event = gtk_window_button_press_event;
   widget_class->style_set = gtk_window_style_set;
+  widget_class->popup_menu = gtk_window_popup_menu;
 
   widget_class->expose_event = gtk_window_expose;
 
@@ -5342,9 +5348,11 @@ static void
 gtk_window_unrealize (GtkWidget *widget)
 {
   GtkWindow *window;
+  GtkWindowPrivate *priv;
   GtkWindowGeometryInfo *info;
 
   window = GTK_WINDOW (widget);
+  priv = GTK_WINDOW_GET_PRIVATE (window);
 
   /* On unrealize, we reset the size of the window such
    * that we will re-apply the default sizing stuff
@@ -5365,6 +5373,12 @@ gtk_window_unrealize (GtkWidget *widget)
       /* be sure we reset geom hints on re-realize */
       info->last.flags = 0;
     }
+
+  if (priv->popup_menu)
+    {
+      gtk_widget_destroy (priv->popup_menu);
+      priv->popup_menu = NULL;
+    }
   
   if (window->frame)
     {
@@ -6001,29 +6015,38 @@ gtk_window_button_press_event (GtkWidget      *widget,
 
       if (event->type == GDK_BUTTON_PRESS)
         {
-          switch (region)
+          if (event->button == 1)
             {
-            case GTK_WINDOW_REGION_TITLE:
-            case GTK_WINDOW_REGION_INNER:
-            case GTK_WINDOW_REGION_EDGE:
-              gtk_window_begin_move_drag (window,
-                                          event->button,
-                                          event->x_root,
-                                          event->y_root,
-                                          event->time);
-              break;
-
-            default:
-              gtk_window_begin_resize_drag (window,
-                                            (GdkWindowEdge)region,
-                                            event->button,
-                                            event->x_root,
-                                            event->y_root,
-                                            event->time);
-              break;
+              switch (region)
+                {
+                case GTK_WINDOW_REGION_TITLE:
+                case GTK_WINDOW_REGION_INNER:
+                case GTK_WINDOW_REGION_EDGE:
+                  gtk_window_begin_move_drag (window,
+                                              event->button,
+                                              event->x_root,
+                                              event->y_root,
+                                              event->time);
+                  break;
+
+                default:
+                  gtk_window_begin_resize_drag (window,
+                                                (GdkWindowEdge)region,
+                                                event->button,
+                                                event->x_root,
+                                                event->y_root,
+                                                event->time);
+                  break;
+                }
+
+              return TRUE;
             }
+          else if (event->button == 3)
+            {
+              gtk_window_do_popup (window, event);
 
-          return TRUE;
+              return TRUE;
+            }
         }
       else if (event->type == GDK_2BUTTON_PRESS)
         {
@@ -6577,6 +6600,67 @@ _gtk_window_unset_focus_and_default (GtkWindow *window,
   g_object_unref (window);
 }
 
+static void
+popup_menu_detach (GtkWidget *widget,
+                   GtkMenu   *menu)
+{
+  GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
+
+  priv->popup_menu = NULL;
+}
+
+static void
+popup_position_func (GtkMenu   *menu,
+                     gint      *x,
+                     gint      *y,
+                     gboolean  *push_in,
+                     gpointer   user_data)
+{
+}
+
+static void
+gtk_window_do_popup (GtkWindow      *window,
+                     GdkEventButton *event)
+{
+  GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
+  GtkWidget *menuitem;
+
+  if (priv->popup_menu)
+    gtk_widget_destroy (priv->popup_menu);
+
+  priv->popup_menu = gtk_menu_new ();
+  gtk_menu_attach_to_widget (GTK_MENU (priv->popup_menu),
+                             GTK_WIDGET (window),
+                             popup_menu_detach);
+
+  menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_CLOSE, NULL);
+  gtk_widget_show (menuitem);
+  gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
+
+  if (event)
+    {
+      gtk_menu_popup (GTK_MENU (priv->popup_menu),
+                      NULL, NULL,
+                      NULL, NULL,
+                      event->button, event->time);
+    }
+  else
+    {
+      gtk_menu_popup (GTK_MENU (priv->popup_menu),
+                      NULL, NULL,
+                      popup_position_func, window,
+                      0, gtk_get_current_event_time ());
+    }
+}
+
+static gboolean
+gtk_window_popup_menu (GtkWidget *widget)
+{
+  gtk_window_do_popup (GTK_WINDOW (widget), NULL);
+
+  return TRUE;
+}
+
 /*********************************
  * Functions related to resizing *
  *********************************/



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