mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 23:50:41 -05:00
...
This commit is contained in:
parent
d0f6283cf5
commit
c533bc838e
@ -543,38 +543,7 @@ event_queue_callback (MetaEventQueue *queue,
|
||||
break;
|
||||
case ClientMessage:
|
||||
if (window)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
meta_window_client_message (window, event);
|
||||
break;
|
||||
case MappingNotify:
|
||||
break;
|
||||
|
@ -34,6 +34,10 @@ typedef struct _MetaUISlave MetaUISlave;
|
||||
typedef struct _MetaWindow MetaWindow;
|
||||
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
|
||||
{
|
||||
char *name;
|
||||
|
38
src/frame.c
38
src/frame.c
@ -752,6 +752,37 @@ ungrab_action (MetaFrame *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
|
||||
meta_frame_event (MetaFrame *frame,
|
||||
XEvent *event)
|
||||
@ -846,6 +877,8 @@ meta_frame_event (MetaFrame *frame,
|
||||
{
|
||||
int x, y, width, height;
|
||||
MetaFrameInfo info;
|
||||
MetaMessageWindowMenuOps ops;
|
||||
MetaMessageWindowMenuOps insensitive;
|
||||
|
||||
meta_verbose ("Menu control clicked on %s\n",
|
||||
frame->window->desc);
|
||||
@ -864,13 +897,14 @@ meta_frame_event (MetaFrame *frame,
|
||||
XUngrabPointer (frame->window->display->xdisplay,
|
||||
event->xbutton.time);
|
||||
|
||||
get_menu_items (frame, &info, &ops, &insensitive);
|
||||
|
||||
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,
|
||||
ops, insensitive,
|
||||
event->xbutton.time);
|
||||
}
|
||||
}
|
||||
|
41
src/menu.c
41
src/menu.c
@ -24,6 +24,10 @@
|
||||
#include <gdk/gdkx.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 _MenuData MenuData;
|
||||
|
||||
@ -48,7 +52,9 @@ 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_("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
|
||||
@ -218,11 +224,16 @@ meta_window_menu_show (gulong xwindow,
|
||||
|
||||
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;
|
||||
while (i < n_workspaces)
|
||||
{
|
||||
char *label;
|
||||
GtkWidget *mi;
|
||||
MenuData *md;
|
||||
|
||||
label = g_strdup_printf (_("Move to workspace _%d\n"),
|
||||
@ -322,12 +333,12 @@ wmspec_change_state (gboolean add,
|
||||
GdkAtom state2)
|
||||
{
|
||||
XEvent xev;
|
||||
Atom op;
|
||||
gulong op;
|
||||
|
||||
if (add)
|
||||
op = gdk_atom_intern ("_NET_WM_STATE_ADD", FALSE);
|
||||
op = _NET_WM_STATE_ADD;
|
||||
else
|
||||
op = gdk_atom_intern ("_NET_WM_STATE_REMOVE", FALSE);
|
||||
op = _NET_WM_STATE_REMOVE;
|
||||
|
||||
xev.xclient.type = ClientMessage;
|
||||
xev.xclient.serial = 0;
|
||||
@ -381,13 +392,25 @@ activate_cb (GtkWidget *menuitem, gpointer data)
|
||||
break;
|
||||
|
||||
case META_MESSAGE_MENU_MINIMIZE:
|
||||
gdk_window_iconify (md->window);
|
||||
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:
|
||||
gdk_error_trap_push ();
|
||||
gdk_window_maximize (md->window);
|
||||
gdk_flush ();
|
||||
gdk_error_trap_pop ();
|
||||
wmspec_change_state (TRUE, 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_UNSHADE:
|
||||
wmspec_change_state (FALSE, md->window,
|
||||
gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE),
|
||||
0);
|
||||
break;
|
||||
|
||||
case META_MESSAGE_MENU_SHADE:
|
||||
|
@ -24,6 +24,10 @@
|
||||
#include <gdk/gdkx.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 _MenuData MenuData;
|
||||
|
||||
@ -48,7 +52,9 @@ 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_("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
|
||||
@ -218,11 +224,16 @@ meta_window_menu_show (gulong xwindow,
|
||||
|
||||
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;
|
||||
while (i < n_workspaces)
|
||||
{
|
||||
char *label;
|
||||
GtkWidget *mi;
|
||||
MenuData *md;
|
||||
|
||||
label = g_strdup_printf (_("Move to workspace _%d\n"),
|
||||
@ -322,12 +333,12 @@ wmspec_change_state (gboolean add,
|
||||
GdkAtom state2)
|
||||
{
|
||||
XEvent xev;
|
||||
Atom op;
|
||||
gulong op;
|
||||
|
||||
if (add)
|
||||
op = gdk_atom_intern ("_NET_WM_STATE_ADD", FALSE);
|
||||
op = _NET_WM_STATE_ADD;
|
||||
else
|
||||
op = gdk_atom_intern ("_NET_WM_STATE_REMOVE", FALSE);
|
||||
op = _NET_WM_STATE_REMOVE;
|
||||
|
||||
xev.xclient.type = ClientMessage;
|
||||
xev.xclient.serial = 0;
|
||||
@ -381,13 +392,25 @@ activate_cb (GtkWidget *menuitem, gpointer data)
|
||||
break;
|
||||
|
||||
case META_MESSAGE_MENU_MINIMIZE:
|
||||
gdk_window_iconify (md->window);
|
||||
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:
|
||||
gdk_error_trap_push ();
|
||||
gdk_window_maximize (md->window);
|
||||
gdk_flush ();
|
||||
gdk_error_trap_pop ();
|
||||
wmspec_change_state (TRUE, 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_UNSHADE:
|
||||
wmspec_change_state (FALSE, md->window,
|
||||
gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE),
|
||||
0);
|
||||
break;
|
||||
|
||||
case META_MESSAGE_MENU_SHADE:
|
||||
|
@ -132,14 +132,11 @@ typedef enum
|
||||
{
|
||||
META_MESSAGE_MENU_DELETE = 1 << 0,
|
||||
META_MESSAGE_MENU_MINIMIZE = 1 << 1,
|
||||
META_MESSAGE_MENU_MAXIMIZE = 1 << 2,
|
||||
META_MESSAGE_MENU_SHADE = 1 << 3,
|
||||
META_MESSAGE_MENU_WORKSPACES = 1 << 4,
|
||||
META_MESSAGE_MENU_ALL = META_MESSAGE_MENU_DELETE |
|
||||
META_MESSAGE_MENU_MINIMIZE |
|
||||
META_MESSAGE_MENU_MAXIMIZE |
|
||||
META_MESSAGE_MENU_SHADE |
|
||||
META_MESSAGE_MENU_WORKSPACES
|
||||
META_MESSAGE_MENU_UNMAXIMIZE = 1 << 2,
|
||||
META_MESSAGE_MENU_MAXIMIZE = 1 << 3,
|
||||
META_MESSAGE_MENU_UNSHADE = 1 << 4,
|
||||
META_MESSAGE_MENU_SHADE = 1 << 5,
|
||||
META_MESSAGE_MENU_WORKSPACES = 1 << 6
|
||||
} MetaMessageWindowMenuOps;
|
||||
|
||||
struct _MetaMessageShowWindowMenu
|
||||
|
113
src/window.c
113
src/window.c
@ -723,6 +723,119 @@ meta_window_property_notify (MetaWindow *window,
|
||||
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
|
||||
process_property_notify (MetaWindow *window,
|
||||
XPropertyEvent *event)
|
||||
|
@ -144,9 +144,6 @@ gboolean meta_window_configure_request (MetaWindow *window,
|
||||
XEvent *event);
|
||||
gboolean meta_window_property_notify (MetaWindow *window,
|
||||
XEvent *event);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
gboolean meta_window_client_message (MetaWindow *window,
|
||||
XEvent *event);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user