Commit c533bc83 authored by rhp's avatar rhp
Browse files

...

parent d0f6283c
......@@ -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;
......
......@@ -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,7 +877,9 @@ 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);
......@@ -863,14 +896,15 @@ 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);
}
}
......
......@@ -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,21 +392,33 @@ 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:
wmspec_change_state (TRUE, md->window,
gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE),
0);
break;
case META_MESSAGE_MENU_WORKSPACES:
{
int workspace;
......
......@@ -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,21 +392,33 @@ 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:
wmspec_change_state (TRUE, md->window,
gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE),
0);
break;
case META_MESSAGE_MENU_WORKSPACES:
{
int workspace;
......
......@@ -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
......
......@@ -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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment