This commit is contained in:
rhp 2001-06-07 02:42:24 +00:00
parent 0f5fdeb1b1
commit 834452ca2c
14 changed files with 628 additions and 19 deletions

View File

@ -35,6 +35,16 @@ struct _MetaFrameActionGrab
int start_button;
};
/* This lacks ButtonReleaseMask to avoid the auto-grab
* since it breaks our popup menu
*/
#define EVENT_MASK (StructureNotifyMask | SubstructureNotifyMask | \
ExposureMask | \
ButtonPressMask | ButtonReleaseMask | \
PointerMotionMask | PointerMotionHintMask | \
EnterWindowMask | LeaveWindowMask)
static void clear_tip (MetaFrame *frame);
static void
@ -244,14 +254,7 @@ meta_window_ensure_frame (MetaWindow *window)
window->size_hints.win_gravity);
attrs.background_pixel = frame->bg_pixel;
attrs.event_mask =
StructureNotifyMask | SubstructureNotifyMask | ExposureMask |
/* We need OwnerGrabButtonMask because during a button
* press we may need to transfer control to the UI slave.
*/
ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask |
PointerMotionMask | PointerMotionHintMask |
EnterWindowMask | LeaveWindowMask;
attrs.event_mask = EVENT_MASK;
frame->xwindow = XCreateWindow (window->display->xdisplay,
window->screen->xroot,
@ -804,6 +807,38 @@ meta_frame_event (MetaFrame *frame,
frame->grab->start_window_y = frame->window->rect.height;
frame->grab->start_button = event->xbutton.button;
}
else if (control == META_FRAME_CONTROL_MENU &&
event->xbutton.button == 1)
{
int x, y, width, height;
MetaFrameInfo info;
meta_verbose ("Menu control clicked on %s\n",
frame->window->desc);
meta_frame_init_info (frame, &info);
frame->window->screen->engine->get_control_rect (&info,
META_FRAME_CONTROL_MENU,
&x, &y, &width, &height,
frame->theme_data);
/* Let the menu get a grab. The user could release button
* before the menu gets the grab, in which case the
* menu gets somewhat confused, but it's not that
* disastrous.
*/
XUngrabPointer (frame->window->display->xdisplay,
event->xbutton.time);
meta_ui_slave_show_window_menu (frame->window->screen->uislave,
frame->window,
frame->rect.x + x,
frame->rect.y + y + height,
event->xbutton.button,
META_MESSAGE_MENU_ALL,
META_MESSAGE_MENU_MINIMIZE,
event->xbutton.time);
}
}
break;
case ButtonRelease:

View File

@ -52,7 +52,17 @@ struct _MetaKeyBinding
static MetaKeyBinding bindings[] = {
{ XK_F1, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (0), 0 },
{ XK_F2, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (1), 0 }
{ XK_F2, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (1), 0 },
{ XK_F3, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (2), 0 },
{ XK_F4, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (3), 0 },
{ XK_F5, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (4), 0 },
{ XK_F6, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (5), 0 },
{ XK_1, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (0), 0 },
{ XK_2, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (1), 0 },
{ XK_3, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (2), 0 },
{ XK_4, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (3), 0 },
{ XK_5, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (4), 0 },
{ XK_6, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (5), 0 }
};
void

190
src/menu.c Normal file
View File

@ -0,0 +1,190 @@
/* Metacity window menu */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "menu.h"
#include "main.h"
#include <gdk/gdkx.h>
typedef struct _MenuItem MenuItem;
typedef struct _MenuData MenuData;
struct _MenuItem
{
MetaMessageWindowMenuOps op;
const char *stock_id;
const char *label;
};
struct _MenuData
{
GdkWindow *window;
MetaMessageWindowMenuOps op;
};
static void activate_cb (GtkWidget *menuitem, gpointer data);
static GtkWidget *menu = NULL;
static MenuItem menuitems[] = {
{ META_MESSAGE_MENU_DELETE, GTK_STOCK_CLOSE, N_("Close") },
{ META_MESSAGE_MENU_MINIMIZE, NULL, N_("Minimize") },
{ META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Maximize") }
};
static void
popup_position_func (GtkMenu *menu,
gint *x,
gint *y,
gboolean *push_in,
gpointer user_data)
{
GtkRequisition req;
GdkPoint *pos;
pos = user_data;
gtk_widget_size_request (GTK_WIDGET (menu), &req);
*x = pos->x;
*y = pos->y;
/* Ensure onscreen */
*x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width));
*y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
}
void
meta_window_menu_show (gulong xwindow,
int root_x, int root_y,
int button,
MetaMessageWindowMenuOps ops,
MetaMessageWindowMenuOps insensitive,
guint32 timestamp)
{
int i;
GdkWindow *window;
GdkPoint *pt;
if (menu)
gtk_widget_destroy (menu);
window = gdk_xid_table_lookup (xwindow);
if (window)
g_object_ref (G_OBJECT (window));
else
window = gdk_window_foreign_new (xwindow);
/* X error creating the foreign window means NULL here */
if (window == NULL)
return;
menu = gtk_menu_new ();
i = 0;
while (i < G_N_ELEMENTS (menuitems))
{
if (ops & menuitems[i].op)
{
GtkWidget *mi;
MenuData *md;
if (menuitems[i].stock_id)
{
GtkWidget *image;
mi = gtk_image_menu_item_new_with_label (menuitems[i].label);
image = gtk_image_new_from_stock (menuitems[i].stock_id,
GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi),
image);
gtk_widget_show (image);
}
else
{
mi = gtk_menu_item_new_with_label (menuitems[i].label);
}
if (insensitive & menuitems[i].op)
gtk_widget_set_sensitive (mi, FALSE);
md = g_new (MenuData, 1);
md->window = window;
md->op = menuitems[i].op;
gtk_signal_connect (GTK_OBJECT (mi),
"activate",
GTK_SIGNAL_FUNC (activate_cb),
md);
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
mi);
gtk_widget_show (mi);
}
++i;
}
gtk_signal_connect (GTK_OBJECT (menu),
"destroy",
GTK_SIGNAL_FUNC (gtk_widget_destroyed),
&menu);
pt = g_new (GdkPoint, 1);
g_object_set_data_full (G_OBJECT (menu),
"destroy-point",
pt,
g_free);
pt->x = root_x;
pt->y = root_y;
gtk_menu_popup (GTK_MENU (menu),
NULL, NULL,
popup_position_func, pt,
button,
timestamp);
if (!GTK_MENU_SHELL (menu)->have_xgrab)
meta_ui_warning ("GtkMenu failed to grab the pointer\n");
}
void
meta_window_menu_hide (void)
{
if (menu)
gtk_widget_destroy (menu);
}
static void
activate_cb (GtkWidget *menuitem, gpointer data)
{
MenuData *md;
md = data;
meta_ui_warning ("Activated menuitem\n");
gtk_widget_destroy (menu);
g_object_unref (G_OBJECT (md->window));
g_free (md);
}

39
src/menu.h Normal file
View File

@ -0,0 +1,39 @@
/* Metacity window menu */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_MENU_H
#define META_MENU_H
#include <gtk/gtk.h>
#include "messages.h"
void meta_window_menu_show (gulong xwindow,
int root_x,
int root_y,
int button,
MetaMessageWindowMenuOps ops,
MetaMessageWindowMenuOps insensitive,
guint32 timestamp);
void meta_window_menu_hide (void);
#endif

View File

@ -108,7 +108,11 @@ meta_screen_new (MetaDisplay *display,
* so create that required workspace.
*/
screen->active_workspace = meta_workspace_new (screen);
/* FIXME, for debugging create another one. */
/* FIXME, for now there are always 6 workspaces... */
meta_workspace_new (screen);
meta_workspace_new (screen);
meta_workspace_new (screen);
meta_workspace_new (screen);
meta_workspace_new (screen);
meta_screen_init_visual_info (screen);

View File

@ -71,12 +71,10 @@ void meta_screen_foreach_window (MetaScreen *scree
MetaScreenWindowFunc func,
gpointer data);
void meta_screen_queue_frame_redraws (MetaScreen *screen);
void meta_screen_show_tip (MetaScreen *screen,
int root_x,
int root_y,
const char *markup);
void meta_screen_hide_tip (MetaScreen *screen);
#endif

View File

@ -20,6 +20,7 @@
*/
#include "uislave.h"
#include "window.h"
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
@ -317,3 +318,42 @@ meta_ui_slave_hide_tip (MetaUISlave *uislave)
send_message (uislave, (MetaMessage*)&hidetip);
}
void
meta_ui_slave_show_window_menu (MetaUISlave *uislave,
MetaWindow *window,
int root_x,
int root_y,
int button,
MetaMessageWindowMenuOps ops,
MetaMessageWindowMenuOps insensitive,
Time timestamp)
{
MetaMessageShowWindowMenu showmenu;
memset (&showmenu, 0, META_MESSAGE_LENGTH (MetaMessageShowWindowMenu));
showmenu.header.message_code = MetaMessageShowWindowMenuCode;
showmenu.header.length = META_MESSAGE_LENGTH (MetaMessageShowWindowMenu);
showmenu.window = window->xwindow;
showmenu.root_x = root_x;
showmenu.root_y = root_y;
showmenu.button = button;
showmenu.ops = ops;
showmenu.insensitive = insensitive;
showmenu.timestamp = timestamp;
send_message (uislave, (MetaMessage*)&showmenu);
}
void
meta_ui_slave_hide_window_menu (MetaUISlave *uislave)
{
MetaMessageHideWindowMenu hidemenu;
memset (&hidemenu, 0, META_MESSAGE_LENGTH (MetaMessageHideWindowMenu));
hidemenu.header.message_code = MetaMessageHideWindowMenuCode;
hidemenu.header.length = META_MESSAGE_LENGTH (MetaMessageHideWindowMenu);
send_message (uislave, (MetaMessage*)&hidemenu);
}

View File

@ -64,4 +64,15 @@ void meta_ui_slave_show_tip (MetaUISlave *uislave,
const char *markup_text);
void meta_ui_slave_hide_tip (MetaUISlave *uislave);
void meta_ui_slave_show_window_menu (MetaUISlave *uislave,
MetaWindow *window,
int root_x,
int root_y,
int button,
MetaMessageWindowMenuOps ops,
MetaMessageWindowMenuOps insensitive,
Time timestamp);
void meta_ui_slave_hide_window_menu (MetaUISlave *uislave);
#endif

View File

@ -5,6 +5,8 @@ metacity_uislave_SOURCES = \
fixedtip.h \
fixedtip.c \
main.c \
menu.c \
menu.h \
messages.c \
messages.h \
messagequeue.c \

View File

@ -23,6 +23,7 @@
#include "messagequeue.h"
#include "fixedtip.h"
#include "main.h"
#include "menu.h"
#include <stdio.h>
#include <string.h>
@ -68,6 +69,20 @@ message_callback (MetaMessageQueue *mq,
meta_fixed_tip_hide ();
break;
case MetaMessageShowWindowMenuCode:
meta_window_menu_show (message->show_menu.window,
message->show_menu.root_x,
message->show_menu.root_y,
message->show_menu.button,
message->show_menu.ops,
message->show_menu.insensitive,
message->show_menu.timestamp);
break;
case MetaMessageHideWindowMenuCode:
meta_window_menu_hide ();
break;
default:
meta_ui_warning ("Unhandled message code %d\n",
message->header.message_code);
@ -88,6 +103,7 @@ meta_ui_warning (const char *format, ...)
va_end (args);
fputs (str, stderr);
fflush (stderr); /* though stderr is unbuffered right */
g_free (str);
}

View File

@ -26,6 +26,7 @@ void meta_ui_warning (const char *format, ...);
/* FIXME */
#define _(x) x
#define N_(x) x
#endif

190
src/uislave/menu.c Normal file
View File

@ -0,0 +1,190 @@
/* Metacity window menu */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "menu.h"
#include "main.h"
#include <gdk/gdkx.h>
typedef struct _MenuItem MenuItem;
typedef struct _MenuData MenuData;
struct _MenuItem
{
MetaMessageWindowMenuOps op;
const char *stock_id;
const char *label;
};
struct _MenuData
{
GdkWindow *window;
MetaMessageWindowMenuOps op;
};
static void activate_cb (GtkWidget *menuitem, gpointer data);
static GtkWidget *menu = NULL;
static MenuItem menuitems[] = {
{ META_MESSAGE_MENU_DELETE, GTK_STOCK_CLOSE, N_("Close") },
{ META_MESSAGE_MENU_MINIMIZE, NULL, N_("Minimize") },
{ META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Maximize") }
};
static void
popup_position_func (GtkMenu *menu,
gint *x,
gint *y,
gboolean *push_in,
gpointer user_data)
{
GtkRequisition req;
GdkPoint *pos;
pos = user_data;
gtk_widget_size_request (GTK_WIDGET (menu), &req);
*x = pos->x;
*y = pos->y;
/* Ensure onscreen */
*x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width));
*y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
}
void
meta_window_menu_show (gulong xwindow,
int root_x, int root_y,
int button,
MetaMessageWindowMenuOps ops,
MetaMessageWindowMenuOps insensitive,
guint32 timestamp)
{
int i;
GdkWindow *window;
GdkPoint *pt;
if (menu)
gtk_widget_destroy (menu);
window = gdk_xid_table_lookup (xwindow);
if (window)
g_object_ref (G_OBJECT (window));
else
window = gdk_window_foreign_new (xwindow);
/* X error creating the foreign window means NULL here */
if (window == NULL)
return;
menu = gtk_menu_new ();
i = 0;
while (i < G_N_ELEMENTS (menuitems))
{
if (ops & menuitems[i].op)
{
GtkWidget *mi;
MenuData *md;
if (menuitems[i].stock_id)
{
GtkWidget *image;
mi = gtk_image_menu_item_new_with_label (menuitems[i].label);
image = gtk_image_new_from_stock (menuitems[i].stock_id,
GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi),
image);
gtk_widget_show (image);
}
else
{
mi = gtk_menu_item_new_with_label (menuitems[i].label);
}
if (insensitive & menuitems[i].op)
gtk_widget_set_sensitive (mi, FALSE);
md = g_new (MenuData, 1);
md->window = window;
md->op = menuitems[i].op;
gtk_signal_connect (GTK_OBJECT (mi),
"activate",
GTK_SIGNAL_FUNC (activate_cb),
md);
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
mi);
gtk_widget_show (mi);
}
++i;
}
gtk_signal_connect (GTK_OBJECT (menu),
"destroy",
GTK_SIGNAL_FUNC (gtk_widget_destroyed),
&menu);
pt = g_new (GdkPoint, 1);
g_object_set_data_full (G_OBJECT (menu),
"destroy-point",
pt,
g_free);
pt->x = root_x;
pt->y = root_y;
gtk_menu_popup (GTK_MENU (menu),
NULL, NULL,
popup_position_func, pt,
button,
timestamp);
if (!GTK_MENU_SHELL (menu)->have_xgrab)
meta_ui_warning ("GtkMenu failed to grab the pointer\n");
}
void
meta_window_menu_hide (void)
{
if (menu)
gtk_widget_destroy (menu);
}
static void
activate_cb (GtkWidget *menuitem, gpointer data)
{
MenuData *md;
md = data;
meta_ui_warning ("Activated menuitem\n");
gtk_widget_destroy (menu);
g_object_unref (G_OBJECT (md->window));
g_free (md);
}

39
src/uislave/menu.h Normal file
View File

@ -0,0 +1,39 @@
/* Metacity window menu */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_MENU_H
#define META_MENU_H
#include <gtk/gtk.h>
#include "messages.h"
void meta_window_menu_show (gulong xwindow,
int root_x,
int root_y,
int button,
MetaMessageWindowMenuOps ops,
MetaMessageWindowMenuOps insensitive,
guint32 timestamp);
void meta_window_menu_hide (void);
#endif

View File

@ -60,12 +60,14 @@
#define META_MESSAGE_MAX_HOST_ALIAS_LEN 50
#define META_MESSAGE_MAX_TIP_LEN 128
typedef union _MetaMessage MetaMessage;
typedef struct _MetaMessageHeader MetaMessageHeader;
typedef struct _MetaMessageFooter MetaMessageFooter;
typedef struct _MetaMessageCheck MetaMessageCheck;
typedef struct _MetaMessageShowTip MetaMessageShowTip;
typedef struct _MetaMessageHideTip MetaMessageHideTip;
typedef union _MetaMessage MetaMessage;
typedef struct _MetaMessageHeader MetaMessageHeader;
typedef struct _MetaMessageFooter MetaMessageFooter;
typedef struct _MetaMessageCheck MetaMessageCheck;
typedef struct _MetaMessageShowTip MetaMessageShowTip;
typedef struct _MetaMessageHideTip MetaMessageHideTip;
typedef struct _MetaMessageShowWindowMenu MetaMessageShowWindowMenu;
typedef struct _MetaMessageHideWindowMenu MetaMessageHideWindowMenu;
typedef enum
{
@ -75,7 +77,9 @@ typedef enum
MetaMessageNullCode,
MetaMessageCheckCode,
MetaMessageShowTipCode,
MetaMessageHideTipCode
MetaMessageHideTipCode,
MetaMessageShowWindowMenuCode,
MetaMessageHideWindowMenuCode
} MetaMessageCode;
struct _MetaMessageHeader
@ -124,12 +128,42 @@ struct _MetaMessageHideTip
MetaMessageFooter footer;
};
typedef enum
{
META_MESSAGE_MENU_DELETE = 1 << 0,
META_MESSAGE_MENU_MINIMIZE = 1 << 1,
META_MESSAGE_MENU_MAXIMIZE = 1 << 2,
META_MESSAGE_MENU_ALL = META_MESSAGE_MENU_DELETE | META_MESSAGE_MENU_MINIMIZE | META_MESSAGE_MENU_MAXIMIZE
} MetaMessageWindowMenuOps;
struct _MetaMessageShowWindowMenu
{
MetaMessageHeader header;
MetaMessageWindowMenuOps ops;
MetaMessageWindowMenuOps insensitive;
gulong window;
int root_x;
int root_y;
guint32 timestamp;
int button;
MetaMessageFooter footer;
};
struct _MetaMessageHideWindowMenu
{
MetaMessageHeader header;
MetaMessageFooter footer;
};
union _MetaMessage
{
MetaMessageHeader header;
MetaMessageCheck check;
MetaMessageShowTip show_tip;
MetaMessageShowTip hide_tip;
MetaMessageShowWindowMenu show_menu;
MetaMessageHideWindowMenu hide_menu;
};
/* Slave-side message send/read code */