This commit is contained in:
rhp 2001-06-09 06:08:44 +00:00
parent d0f6283cf5
commit c533bc838e
8 changed files with 228 additions and 68 deletions

View File

@ -543,38 +543,7 @@ event_queue_callback (MetaEventQueue *queue,
break; break;
case ClientMessage: case ClientMessage:
if (window) if (window)
{ meta_window_client_message (window, event);
if (event->xclient.message_type ==
display->atom_net_close_window)
{
/* I think the wm spec should maybe put a time
* in this message, CurrentTime here is sort of
* bogus. But it rarely matters most likely.
*/
meta_window_delete (window, CurrentTime);
}
else if (event->xclient.message_type ==
display->atom_net_wm_desktop)
{
int space;
MetaWorkspace *workspace;
space = event->xclient.data.l[0];
meta_verbose ("Request to move %s to screen workspace %d\n",
window->desc, space);
workspace =
meta_display_get_workspace_by_screen_index (display,
window->screen,
space);
if (workspace)
meta_window_change_workspace (window, workspace);
else
meta_verbose ("No such workspace %d for screen\n", space);
}
}
break; break;
case MappingNotify: case MappingNotify:
break; break;

View File

@ -34,6 +34,10 @@ typedef struct _MetaUISlave MetaUISlave;
typedef struct _MetaWindow MetaWindow; typedef struct _MetaWindow MetaWindow;
typedef struct _MetaWorkspace MetaWorkspace; typedef struct _MetaWorkspace MetaWorkspace;
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
#define _NET_WM_STATE_ADD 1 /* add/set property */
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
struct _MetaDisplay struct _MetaDisplay
{ {
char *name; char *name;

View File

@ -752,6 +752,37 @@ ungrab_action (MetaFrame *frame,
queue_tip (frame); queue_tip (frame);
} }
static void
get_menu_items (MetaFrame *frame,
MetaFrameInfo *info,
MetaMessageWindowMenuOps *ops,
MetaMessageWindowMenuOps *insensitive)
{
*ops = 0;
*insensitive = 0;
if (info->flags & META_FRAME_CONTROL_MAXIMIZE)
{
if (frame->window->maximized)
*ops |= META_MESSAGE_MENU_UNMAXIMIZE;
else
*ops |= META_MESSAGE_MENU_MAXIMIZE;
}
if (frame->window->shaded)
*ops |= META_MESSAGE_MENU_UNSHADE;
else
*ops |= META_MESSAGE_MENU_SHADE;
*ops |= (META_MESSAGE_MENU_DELETE | META_MESSAGE_MENU_WORKSPACES | META_MESSAGE_MENU_MINIMIZE);
if (!(info->flags & META_FRAME_CONTROL_MINIMIZE))
*insensitive |= META_MESSAGE_MENU_MINIMIZE;
if (!(info->flags & META_FRAME_CONTROL_DELETE))
*insensitive |= META_MESSAGE_MENU_DELETE;
}
gboolean gboolean
meta_frame_event (MetaFrame *frame, meta_frame_event (MetaFrame *frame,
XEvent *event) XEvent *event)
@ -846,7 +877,9 @@ meta_frame_event (MetaFrame *frame,
{ {
int x, y, width, height; int x, y, width, height;
MetaFrameInfo info; MetaFrameInfo info;
MetaMessageWindowMenuOps ops;
MetaMessageWindowMenuOps insensitive;
meta_verbose ("Menu control clicked on %s\n", meta_verbose ("Menu control clicked on %s\n",
frame->window->desc); frame->window->desc);
@ -863,14 +896,15 @@ meta_frame_event (MetaFrame *frame,
*/ */
XUngrabPointer (frame->window->display->xdisplay, XUngrabPointer (frame->window->display->xdisplay,
event->xbutton.time); event->xbutton.time);
get_menu_items (frame, &info, &ops, &insensitive);
meta_ui_slave_show_window_menu (frame->window->screen->uislave, meta_ui_slave_show_window_menu (frame->window->screen->uislave,
frame->window, frame->window,
frame->rect.x + x, frame->rect.x + x,
frame->rect.y + y + height, frame->rect.y + y + height,
event->xbutton.button, event->xbutton.button,
META_MESSAGE_MENU_ALL, ops, insensitive,
META_MESSAGE_MENU_MINIMIZE,
event->xbutton.time); event->xbutton.time);
} }
} }

View File

@ -24,6 +24,10 @@
#include <gdk/gdkx.h> #include <gdk/gdkx.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
#define _NET_WM_STATE_ADD 1 /* add/set property */
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
typedef struct _MenuItem MenuItem; typedef struct _MenuItem MenuItem;
typedef struct _MenuData MenuData; typedef struct _MenuData MenuData;
@ -48,7 +52,9 @@ static MenuItem menuitems[] = {
{ META_MESSAGE_MENU_DELETE, GTK_STOCK_CLOSE, N_("_Close") }, { META_MESSAGE_MENU_DELETE, GTK_STOCK_CLOSE, N_("_Close") },
{ META_MESSAGE_MENU_MINIMIZE, NULL, N_("_Minimize") }, { META_MESSAGE_MENU_MINIMIZE, NULL, N_("_Minimize") },
{ META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Ma_ximize") }, { META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Ma_ximize") },
{ META_MESSAGE_MENU_SHADE, NULL, N_("_Shade") } { META_MESSAGE_MENU_UNMAXIMIZE, NULL, N_("_Unmaximize") },
{ META_MESSAGE_MENU_SHADE, NULL, N_("_Shade") },
{ META_MESSAGE_MENU_UNSHADE, NULL, N_("U_nshade") }
}; };
static void static void
@ -218,11 +224,16 @@ meta_window_menu_show (gulong xwindow,
if (n_workspaces > 0 && current_workspace >= 0) if (n_workspaces > 0 && current_workspace >= 0)
{ {
GtkWidget *mi;
mi = gtk_separator_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
gtk_widget_show (mi);
i = 0; i = 0;
while (i < n_workspaces) while (i < n_workspaces)
{ {
char *label; char *label;
GtkWidget *mi;
MenuData *md; MenuData *md;
label = g_strdup_printf (_("Move to workspace _%d\n"), label = g_strdup_printf (_("Move to workspace _%d\n"),
@ -322,12 +333,12 @@ wmspec_change_state (gboolean add,
GdkAtom state2) GdkAtom state2)
{ {
XEvent xev; XEvent xev;
Atom op; gulong op;
if (add) if (add)
op = gdk_atom_intern ("_NET_WM_STATE_ADD", FALSE); op = _NET_WM_STATE_ADD;
else else
op = gdk_atom_intern ("_NET_WM_STATE_REMOVE", FALSE); op = _NET_WM_STATE_REMOVE;
xev.xclient.type = ClientMessage; xev.xclient.type = ClientMessage;
xev.xclient.serial = 0; xev.xclient.serial = 0;
@ -381,21 +392,33 @@ activate_cb (GtkWidget *menuitem, gpointer data)
break; break;
case META_MESSAGE_MENU_MINIMIZE: case META_MESSAGE_MENU_MINIMIZE:
gdk_window_iconify (md->window);
break; break;
case META_MESSAGE_MENU_UNMAXIMIZE:
wmspec_change_state (FALSE, md->window,
gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE),
gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE));
break;
case META_MESSAGE_MENU_MAXIMIZE: case META_MESSAGE_MENU_MAXIMIZE:
gdk_error_trap_push (); wmspec_change_state (TRUE, md->window,
gdk_window_maximize (md->window); gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE),
gdk_flush (); gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE));
gdk_error_trap_pop ();
break; break;
case META_MESSAGE_MENU_UNSHADE:
wmspec_change_state (FALSE, md->window,
gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE),
0);
break;
case META_MESSAGE_MENU_SHADE: case META_MESSAGE_MENU_SHADE:
wmspec_change_state (TRUE, md->window, wmspec_change_state (TRUE, md->window,
gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE), gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE),
0); 0);
break; break;
case META_MESSAGE_MENU_WORKSPACES: case META_MESSAGE_MENU_WORKSPACES:
{ {
int workspace; int workspace;

View File

@ -24,6 +24,10 @@
#include <gdk/gdkx.h> #include <gdk/gdkx.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
#define _NET_WM_STATE_ADD 1 /* add/set property */
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
typedef struct _MenuItem MenuItem; typedef struct _MenuItem MenuItem;
typedef struct _MenuData MenuData; typedef struct _MenuData MenuData;
@ -48,7 +52,9 @@ static MenuItem menuitems[] = {
{ META_MESSAGE_MENU_DELETE, GTK_STOCK_CLOSE, N_("_Close") }, { META_MESSAGE_MENU_DELETE, GTK_STOCK_CLOSE, N_("_Close") },
{ META_MESSAGE_MENU_MINIMIZE, NULL, N_("_Minimize") }, { META_MESSAGE_MENU_MINIMIZE, NULL, N_("_Minimize") },
{ META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Ma_ximize") }, { META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Ma_ximize") },
{ META_MESSAGE_MENU_SHADE, NULL, N_("_Shade") } { META_MESSAGE_MENU_UNMAXIMIZE, NULL, N_("_Unmaximize") },
{ META_MESSAGE_MENU_SHADE, NULL, N_("_Shade") },
{ META_MESSAGE_MENU_UNSHADE, NULL, N_("U_nshade") }
}; };
static void static void
@ -218,11 +224,16 @@ meta_window_menu_show (gulong xwindow,
if (n_workspaces > 0 && current_workspace >= 0) if (n_workspaces > 0 && current_workspace >= 0)
{ {
GtkWidget *mi;
mi = gtk_separator_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
gtk_widget_show (mi);
i = 0; i = 0;
while (i < n_workspaces) while (i < n_workspaces)
{ {
char *label; char *label;
GtkWidget *mi;
MenuData *md; MenuData *md;
label = g_strdup_printf (_("Move to workspace _%d\n"), label = g_strdup_printf (_("Move to workspace _%d\n"),
@ -322,12 +333,12 @@ wmspec_change_state (gboolean add,
GdkAtom state2) GdkAtom state2)
{ {
XEvent xev; XEvent xev;
Atom op; gulong op;
if (add) if (add)
op = gdk_atom_intern ("_NET_WM_STATE_ADD", FALSE); op = _NET_WM_STATE_ADD;
else else
op = gdk_atom_intern ("_NET_WM_STATE_REMOVE", FALSE); op = _NET_WM_STATE_REMOVE;
xev.xclient.type = ClientMessage; xev.xclient.type = ClientMessage;
xev.xclient.serial = 0; xev.xclient.serial = 0;
@ -381,21 +392,33 @@ activate_cb (GtkWidget *menuitem, gpointer data)
break; break;
case META_MESSAGE_MENU_MINIMIZE: case META_MESSAGE_MENU_MINIMIZE:
gdk_window_iconify (md->window);
break; break;
case META_MESSAGE_MENU_UNMAXIMIZE:
wmspec_change_state (FALSE, md->window,
gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE),
gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE));
break;
case META_MESSAGE_MENU_MAXIMIZE: case META_MESSAGE_MENU_MAXIMIZE:
gdk_error_trap_push (); wmspec_change_state (TRUE, md->window,
gdk_window_maximize (md->window); gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE),
gdk_flush (); gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE));
gdk_error_trap_pop ();
break; break;
case META_MESSAGE_MENU_UNSHADE:
wmspec_change_state (FALSE, md->window,
gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE),
0);
break;
case META_MESSAGE_MENU_SHADE: case META_MESSAGE_MENU_SHADE:
wmspec_change_state (TRUE, md->window, wmspec_change_state (TRUE, md->window,
gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE), gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE),
0); 0);
break; break;
case META_MESSAGE_MENU_WORKSPACES: case META_MESSAGE_MENU_WORKSPACES:
{ {
int workspace; int workspace;

View File

@ -132,14 +132,11 @@ typedef enum
{ {
META_MESSAGE_MENU_DELETE = 1 << 0, META_MESSAGE_MENU_DELETE = 1 << 0,
META_MESSAGE_MENU_MINIMIZE = 1 << 1, META_MESSAGE_MENU_MINIMIZE = 1 << 1,
META_MESSAGE_MENU_MAXIMIZE = 1 << 2, META_MESSAGE_MENU_UNMAXIMIZE = 1 << 2,
META_MESSAGE_MENU_SHADE = 1 << 3, META_MESSAGE_MENU_MAXIMIZE = 1 << 3,
META_MESSAGE_MENU_WORKSPACES = 1 << 4, META_MESSAGE_MENU_UNSHADE = 1 << 4,
META_MESSAGE_MENU_ALL = META_MESSAGE_MENU_DELETE | META_MESSAGE_MENU_SHADE = 1 << 5,
META_MESSAGE_MENU_MINIMIZE | META_MESSAGE_MENU_WORKSPACES = 1 << 6
META_MESSAGE_MENU_MAXIMIZE |
META_MESSAGE_MENU_SHADE |
META_MESSAGE_MENU_WORKSPACES
} MetaMessageWindowMenuOps; } MetaMessageWindowMenuOps;
struct _MetaMessageShowWindowMenu struct _MetaMessageShowWindowMenu

View File

@ -723,6 +723,119 @@ meta_window_property_notify (MetaWindow *window,
return process_property_notify (window, &event->xproperty); return process_property_notify (window, &event->xproperty);
} }
gboolean
meta_window_client_message (MetaWindow *window,
XEvent *event)
{
MetaDisplay *display;
display = window->display;
if (event->xclient.message_type ==
display->atom_net_close_window)
{
/* I think the wm spec should maybe put a time
* in this message, CurrentTime here is sort of
* bogus. But it rarely matters most likely.
*/
meta_window_delete (window, CurrentTime);
return TRUE;
}
else if (event->xclient.message_type ==
display->atom_net_wm_desktop)
{
int space;
MetaWorkspace *workspace;
space = event->xclient.data.l[0];
meta_verbose ("Request to move %s to screen workspace %d\n",
window->desc, space);
workspace =
meta_display_get_workspace_by_screen_index (display,
window->screen,
space);
if (workspace)
meta_window_change_workspace (window, workspace);
else
meta_verbose ("No such workspace %d for screen\n", space);
return TRUE;
}
else if (event->xclient.message_type ==
display->atom_net_wm_state)
{
gulong action;
Atom first;
Atom second;
action = event->xclient.data.l[0];
first = event->xclient.data.l[1];
second = event->xclient.data.l[2];
if (meta_is_verbose ())
{
char *str1;
char *str2;
meta_error_trap_push (display);
str1 = XGetAtomName (display->xdisplay, first);
if (meta_error_trap_pop (display))
str1 = NULL;
meta_error_trap_push (display);
str2 = XGetAtomName (display->xdisplay, second);
if (meta_error_trap_pop (display))
str2 = NULL;
meta_verbose ("Request to change _NET_WM_STATE action %ld atom1: %s atom2: %s\n",
action,
str1 ? str1 : "(unknown)",
str2 ? str2 : "(unknown)");
if (str1)
XFree (str1);
if (str2)
XFree (str2);
}
if (first == display->atom_net_wm_state_shaded ||
second == display->atom_net_wm_state_shaded)
{
gboolean shade;
shade = (action == _NET_WM_STATE_ADD ||
(action == _NET_WM_STATE_TOGGLE && !window->shaded));
if (shade)
meta_window_shade (window);
else
meta_window_unshade (window);
}
if (first == display->atom_net_wm_state_maximized_horz ||
second == display->atom_net_wm_state_maximized_horz ||
first == display->atom_net_wm_state_maximized_vert ||
second == display->atom_net_wm_state_maximized_vert)
{
gboolean max;
max = (action == _NET_WM_STATE_ADD ||
(action == _NET_WM_STATE_TOGGLE && !window->maximized));
if (max)
meta_window_maximize (window);
else
meta_window_unmaximize (window);
}
return TRUE;
}
return FALSE;
}
static gboolean static gboolean
process_property_notify (MetaWindow *window, process_property_notify (MetaWindow *window,
XPropertyEvent *event) XPropertyEvent *event)

View File

@ -144,9 +144,6 @@ gboolean meta_window_configure_request (MetaWindow *window,
XEvent *event); XEvent *event);
gboolean meta_window_property_notify (MetaWindow *window, gboolean meta_window_property_notify (MetaWindow *window,
XEvent *event); XEvent *event);
gboolean meta_window_client_message (MetaWindow *window,
XEvent *event);
#endif #endif