summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrhp <rhp>2001-06-09 06:08:44 +0000
committerrhp <rhp>2001-06-09 06:08:44 +0000
commitc533bc838e16aab8ac34daadf65e9216b3484b8c (patch)
treeed012dee88018d386d767bdbeb24fe346e62df9d
parentd0f6283cf5e11a3c15fd6c7b7e6d7beb7bf55900 (diff)
downloadmetacity-c533bc838e16aab8ac34daadf65e9216b3484b8c.tar.gz
...
-rw-r--r--src/display.c33
-rw-r--r--src/display.h4
-rw-r--r--src/frame.c40
-rw-r--r--src/menu.c43
-rw-r--r--src/uislave/menu.c43
-rw-r--r--src/uislave/messages.h13
-rw-r--r--src/window.c113
-rw-r--r--src/window.h7
8 files changed, 228 insertions, 68 deletions
diff --git a/src/display.c b/src/display.c
index df2169a9..51712250 100644
--- a/src/display.c
+++ b/src/display.c
@@ -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;
diff --git a/src/display.h b/src/display.h
index 1b3ef03d..bc24b28e 100644
--- a/src/display.h
+++ b/src/display.h
@@ -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;
diff --git a/src/frame.c b/src/frame.c
index fdeebeef..7d20aa23 100644
--- a/src/frame.c
+++ b/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,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);
}
}
diff --git a/src/menu.c b/src/menu.c
index 5e77abc9..f9687a79 100644
--- a/src/menu.c
+++ b/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,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;
diff --git a/src/uislave/menu.c b/src/uislave/menu.c
index 5e77abc9..f9687a79 100644
--- a/src/uislave/menu.c
+++ b/src/uislave/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,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;
diff --git a/src/uislave/messages.h b/src/uislave/messages.h
index c4fe64c0..15203864 100644
--- a/src/uislave/messages.h
+++ b/src/uislave/messages.h
@@ -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
diff --git a/src/window.c b/src/window.c
index f0ed4dd0..59f4af57 100644
--- a/src/window.c
+++ b/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)
diff --git a/src/window.h b/src/window.h
index 36a27ad1..fdce20e3 100644
--- a/src/window.h
+++ b/src/window.h
@@ -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