summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Adams <readams@readams.net>2004-07-31 19:56:10 +0000
committerRob Adams <readams@src.gnome.org>2004-07-31 19:56:10 +0000
commite60da6c006094db82fe146182afdc1b3d6a633f8 (patch)
tree91877e957d96e9e91a89c92ced16fa8e4bfe879e
parentc2bbd8b66cb55f7462b6f1ffee0ec892794bd337 (diff)
downloadmetacity-e60da6c006094db82fe146182afdc1b3d6a633f8.tar.gz
metacity-e60da6c006094db82fe146182afdc1b3d6a633f8.tar.bz2
Fix some support for EWMH hints, and fix USER_TIME support to include the
2004-07-31 Rob Adams <readams@readams.net> Fix some support for EWMH hints, and fix USER_TIME support to include the DEMANDS_ATTENTION hint. Also includes some code for implementing _NET_RESTACK_WINDOW and _NET_MOVERESIZE_WINDOW, but this is disabled pending feature thaw. * COMPLIANCE: update with new information * src/display.c (meta_display_open): add new hints to list * src/display.h (_MetaDisplay): Add new atoms to struct * src/screen.c (set_supported_hint): update the list of support hints. (set_desktop_viewport_hint): new function sets the viewport hint to (0,0) as required by the spec for WMs with no viewport support. (set_desktop_geometry_hint): new function to set the desktop size hint to the size of the display, since we don't implement large desktop support, as required by the spec. (meta_screen_resize): update the geometry hint on screen resize * src/window.c (meta_window_new_with_attrs): Initialize demands_attention state (set_net_wm_state): Set demands_attention hint in the window state (meta_window_show): If we don't pop up a window because of USER_TIME, set DEMANDS_ATTENTION on the window. (meta_window_focus): When a window receives focus, remove DEMANDS_ATTENTION hint (meta_window_client_message): Allow other apps to set DEMANDS_ATTENTION on a window. Also, if the _NET_ACTIVE_WINDOW hint includes a timestamp, use it. (update_net_wm_state): Read DEMANDS_ATTENTION state also * src/window.h (_MetaWindow): add wm_state_demands_attention bit.
-rw-r--r--COMPLIANCE32
-rw-r--r--ChangeLog36
-rw-r--r--src/display.c125
-rw-r--r--src/display.h5
-rw-r--r--src/screen.c61
-rw-r--r--src/window.c53
-rw-r--r--src/window.h3
7 files changed, 288 insertions, 27 deletions
diff --git a/COMPLIANCE b/COMPLIANCE
index c0e8dce..b45a672 100644
--- a/COMPLIANCE
+++ b/COMPLIANCE
@@ -48,15 +48,12 @@ standard is available at http://freedesktop.org/Standards/wm-spec/
+ _NET_NUMBER_OF_DESKTOPS (1.3)
-- _NET_DESKTOP_GEOMETRY (-)
- Metacity does not implement large desktops. Regardless, according
- to the specification, metacity SHOULD set this property to the
- screen size, and update it if the screen size changes because of a
- RandR change.
++ _NET_DESKTOP_GEOMETRY (1.3)
+ Metacity does not implement large desktops, so this is kept set to
+ the screen size.
-- _NET_DESKTOP_VIEWPORT (-)
- Metacity does not implement viewports. However, according to the
- specification, metacity MUST set this property to (0,0)
++ _NET_DESKTOP_VIEWPORT (1.3)
+ Metacity does not implement viewports, so this is a constant (0,0).
+ _NET_CURRENT_DESKTOP (1.3)
@@ -82,15 +79,16 @@ standard is available at http://freedesktop.org/Standards/wm-spec/
+ _NET_CLOSE_WINDOW (1.3)
-- _NET_MOVERESIZE_WINDOW (-)
- Metacity does not support this message. The specification states
- that metacity should treat this message like a ConfigureRequest.
- Not hard to implement; just hasn't been done.
+- _NET_MOVERESIZE_WINDOW (1.3)
+ Metacity supports this message, but the specification is unclear on
+ the layout of the detail value, and as such it is #if 0'd in the code
+ _NET_WM_MOVERESIZE (1.3)
-- _NET_RESTACK_WINDOW (-)
- Metacity does not currently support this message.
+- _NET_RESTACK_WINDOW (1.3)
+ Metacity will raise or lower windows in response to this message,
+ but the sibling restack modes are not supported, and it is currently
+ #if 0'd in the code.
+ _NET_REQUEST_FRAME_EXTENTS (1.3)
@@ -114,14 +112,14 @@ standard is available at http://freedesktop.org/Standards/wm-spec/
+ _NET_WM_WINDOW_TYPE (1.3)
/ _NET_WM_STATE (1.3)
+ This property is read and updated according to the specification,
+ but see caveat below.
Metacity does not recognize separate vertical and horizontal
maximization states. Currently metacity will do a two-dimensional
maximization if either property is set.
See: http://bugzilla.gnome.org/show_bug.cgi?id=113601
Metacity doesn't implement viewports so _NET_WM_STATE_STICKY is
unimplemented.
- _NET_WM_STATE_DEMANDS_ATTENTION is neither read nor updated by
- metacity. Metacity should unset it on window activation.
+ _NET_WM_ALLOWED_ACTIONS (1.3)
Metacity keeps this hint up to date. The code is somewhat crufty
@@ -141,7 +139,7 @@ standard is available at http://freedesktop.org/Standards/wm-spec/
+ _NET_WM_HANDLED_ICONS (1.3)
Metacity does not read or set this property. However, metacity
- never managed iconified windows, and so has no need to do so.
+ never manages iconified windows, and so has no need to do so.
+ _NET_WM_USER_TIME (1.3)
Metacity uses this property to prevent applications from stealing
diff --git a/ChangeLog b/ChangeLog
index 1ac7418..42d0fe1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+2004-07-31 Rob Adams <readams@readams.net>
+
+ Fix some support for EWMH hints, and fix USER_TIME support to
+ include the DEMANDS_ATTENTION hint. Also includes some code for
+ implementing _NET_RESTACK_WINDOW and _NET_MOVERESIZE_WINDOW, but
+ this is disabled pending feature thaw.
+
+ * COMPLIANCE: update with new information
+
+ * src/display.c (meta_display_open): add new hints to list
+
+ * src/display.h (_MetaDisplay): Add new atoms to struct
+
+ * src/screen.c (set_supported_hint): update the list of support
+ hints.
+ (set_desktop_viewport_hint): new function sets the viewport hint
+ to (0,0) as required by the spec for WMs with no viewport support.
+ (set_desktop_geometry_hint): new function to set the desktop size
+ hint to the size of the display, since we don't implement large
+ desktop support, as required by the spec.
+ (meta_screen_resize): update the geometry hint on screen resize
+
+ * src/window.c (meta_window_new_with_attrs): Initialize
+ demands_attention state
+ (set_net_wm_state): Set demands_attention hint in the window state
+ (meta_window_show): If we don't pop up a window because of
+ USER_TIME, set DEMANDS_ATTENTION on the window.
+ (meta_window_focus): When a window receives focus, remove
+ DEMANDS_ATTENTION hint
+ (meta_window_client_message): Allow other apps to set
+ DEMANDS_ATTENTION on a window. Also, if the _NET_ACTIVE_WINDOW
+ hint includes a timestamp, use it.
+ (update_net_wm_state): Read DEMANDS_ATTENTION state also
+
+ * src/window.h (_MetaWindow): add wm_state_demands_attention bit.
+
2004-07-22 Rob Adams <readams@readams.net>
* src/metacity.schemas.in: Add trailing quotes to keybinding
diff --git a/src/display.c b/src/display.c
index fa574bf..4949ba0 100644
--- a/src/display.c
+++ b/src/display.c
@@ -282,6 +282,11 @@ meta_display_open (const char *name)
"_NET_FRAME_EXTENTS",
"_NET_REQUEST_FRAME_EXTENTS",
"_NET_WM_USER_TIME",
+ "_NET_WM_STATE_DEMANDS_ATTENTION",
+ "_NET_RESTACK_WINDOW",
+ "_NET_MOVERESIZE_WINDOW",
+ "_NET_DESKTOP_GEOMETRY",
+ "_NET_DESKTOP_VIEWPORT"
};
Atom atoms[G_N_ELEMENTS(atom_names)];
@@ -429,6 +434,11 @@ meta_display_open (const char *name)
display->atom_net_frame_extents = atoms[83];
display->atom_net_request_frame_extents = atoms[84];
display->atom_net_wm_user_time = atoms[85];
+ display->atom_net_wm_state_demands_attention = atoms[86];
+ display->atom_net_restack_window = atoms[87];
+ display->atom_net_moveresize_window = atoms[88];
+ display->atom_net_desktop_geometry = atoms[89];
+ display->atom_net_desktop_viewport = atoms[90];
display->prop_hooks = NULL;
meta_display_init_window_prop_hooks (display);
@@ -1170,6 +1180,107 @@ double_click_timeout_for_event (MetaDisplay *display,
return meta_ui_get_double_click_timeout (screen->ui);
}
+#if 0
+static void
+handle_net_moveresize_window (MetaDisplay* display,
+ XEvent *event)
+{
+ MetaWindow *window;
+ int x, y, width, height;
+ gboolean only_resize;
+ unsigned int gravity;
+ unsigned int mode;
+
+ window = meta_display_lookup_x_window (display,
+ event->xclient.window);
+
+ /*
+ * FIXME: The specification seems to have serious endian issues
+ * here. Does bits 8-11 mean the high-order byte, or the low-order
+ * byte?
+ */
+ gravity = (event->xclient.data.l[0] & ~0xff);
+ mode = (event->xclient.data.l[0] & ~0xff00) >> 8;
+
+ if (window)
+ {
+ meta_window_get_gravity_position (window, &x, &y);
+ width = window->rect.width;
+ height = window->rect.height;
+
+ if (mode & (CWX | CWY))
+ only_resize = FALSE;
+ else
+ only_resize = TRUE;
+
+ if (mode & CWX)
+ x = event->xclient.data.l[1];
+ if (mode & CWY)
+ y = event->xclient.data.l[2];
+ if (mode & CWWidth)
+ width = event->xclient.data.l[3];
+ if (mode & CWHeight)
+ height = event->xclient.data.l[4];
+
+ if (only_resize)
+ {
+ if (gravity)
+ meta_window_resize_with_gravity (window,
+ TRUE,
+ width,
+ height,
+ gravity);
+ else
+ meta_window_resize (window,
+ TRUE,
+ width,
+ height);
+ }
+ else
+ {
+ meta_window_move_resize (window,
+ TRUE,
+ x,
+ y,
+ width,
+ height);
+ }
+ }
+}
+
+static void
+handle_net_restack_window (MetaDisplay* display,
+ XEvent *event)
+{
+ MetaWindow *window;
+
+ window = meta_display_lookup_x_window (display,
+ event->xclient.window);
+
+ if (window)
+ {
+ /*
+ * The EWMH includes a sibling for the restack request, but we
+ * don't currently support these types of raises.
+ *
+ */
+ switch (event->xclient.data.l[2])
+ {
+ case Above:
+ meta_window_raise (window);
+ break;
+ case Below:
+ meta_window_lower (window);
+ break;
+ case TopIf:
+ case BottomIf:
+ case Opposite:
+ break;
+ }
+ }
+}
+#endif
+
static gboolean
event_callback (XEvent *event,
gpointer data)
@@ -1873,10 +1984,18 @@ event_callback (XEvent *event,
else if (event->xproperty.atom ==
display->atom_net_desktop_names)
meta_screen_update_workspace_names (screen);
+#if 0
+ else if (event->xproperty.atom ==
+ display->atom_net_restack_window)
+ handle_net_restack_window (display, event);
+ else if (event->xproperty.atom ==
+ display->atom_net_moveresize_window)
+ handle_net_moveresize_window (display, event);
+#endif
- /* we just use this property as a sentinel to avoid
- * certain race conditions. See the comment for the
- * sentinel_counter variable declaration in display.h
+ /* we just use this property as a sentinel to avoid
+ * certain race conditions. See the comment for the
+ * sentinel_counter variable declaration in display.h
*/
if (event->xproperty.atom ==
display->atom_metacity_sentinel)
diff --git a/src/display.h b/src/display.h
index 08255fe..174f053 100644
--- a/src/display.h
+++ b/src/display.h
@@ -176,6 +176,11 @@ struct _MetaDisplay
Atom atom_net_frame_extents;
Atom atom_net_request_frame_extents;
Atom atom_net_wm_user_time;
+ Atom atom_net_wm_state_demands_attention;
+ Atom atom_net_restack_window;
+ Atom atom_net_moveresize_window;
+ Atom atom_net_desktop_geometry;
+ Atom atom_net_desktop_viewport;
/* This is the actual window from focus events,
* not the one we last set
diff --git a/src/screen.c b/src/screen.c
index c08e957..f9e4cd8 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -57,6 +57,9 @@ static void set_workspace_names (MetaScreen *screen);
static void prefs_changed_callback (MetaPreference pref,
gpointer data);
+static void set_desktop_geometry_hint (MetaScreen *screen);
+static void set_desktop_viewport_hint (MetaScreen *screen);
+
#ifdef HAVE_STARTUP_NOTIFICATION
static void meta_screen_sn_event (SnMonitorEvent *event,
void *user_data);
@@ -82,7 +85,7 @@ set_wm_check_hint (MetaScreen *screen)
static int
set_supported_hint (MetaScreen *screen)
{
-#define N_SUPPORTED 54
+#define N_SUPPORTED 58
Atom atoms[N_SUPPORTED];
atoms[0] = screen->display->atom_net_wm_name;
@@ -139,6 +142,12 @@ set_supported_hint (MetaScreen *screen)
atoms[51] = screen->display->atom_net_wm_action_minimize;
atoms[52] = screen->display->atom_net_frame_extents;
atoms[53] = screen->display->atom_net_request_frame_extents;
+ atoms[54] = screen->display->atom_net_wm_user_time;
+ atoms[55] = screen->display->atom_net_wm_state_demands_attention;
+ atoms[56] = screen->display->atom_net_desktop_geometry;
+ atoms[57] = screen->display->atom_net_desktop_viewport;
+ //atoms[58] = screen->display->atom_net_restack_window;
+ //atoms[59] = screen->display->atom_net_moveresize_window;
XChangeProperty (screen->display->xdisplay, screen->xroot,
screen->display->atom_net_supported,
@@ -575,6 +584,10 @@ meta_screen_new (MetaDisplay *display,
set_wm_check_hint (screen);
+ set_desktop_viewport_hint (screen);
+
+ set_desktop_geometry_hint (screen);
+
meta_screen_update_workspace_layout (screen);
/* Get current workspace */
@@ -966,6 +979,51 @@ set_number_of_spaces_hint (MetaScreen *screen,
}
static void
+set_desktop_geometry_hint (MetaScreen *screen)
+{
+ unsigned long data[2];
+
+ if (screen->closing > 0)
+ return;
+
+ data[0] = screen->width;
+ data[1] = screen->height;
+
+ meta_verbose ("Setting _NET_DESKTOP_GEOMETRY to %ld, %ld\n", data[0], data[1]);
+
+ meta_error_trap_push (screen->display);
+ XChangeProperty (screen->display->xdisplay, screen->xroot,
+ screen->display->atom_net_desktop_geometry,
+ XA_CARDINAL,
+ 32, PropModeReplace, (guchar*) data, 2);
+ meta_error_trap_pop (screen->display, FALSE);
+}
+
+static void
+set_desktop_viewport_hint (MetaScreen *screen)
+{
+ unsigned long data[2];
+
+ if (screen->closing > 0)
+ return;
+
+ /*
+ * Metacity does not implement viewports, so this is a fixed 0,0
+ */
+ data[0] = 0;
+ data[1] = 0;
+
+ meta_verbose ("Setting _NET_DESKTOP_VIEWPORT to 0, 0\n");
+
+ meta_error_trap_push (screen->display);
+ XChangeProperty (screen->display->xdisplay, screen->xroot,
+ screen->display->atom_net_desktop_viewport,
+ XA_CARDINAL,
+ 32, PropModeReplace, (guchar*) data, 2);
+ meta_error_trap_pop (screen->display, FALSE);
+}
+
+static void
update_num_workspaces (MetaScreen *screen)
{
int new_num;
@@ -2101,6 +2159,7 @@ meta_screen_resize (MetaScreen *screen,
screen->height = height;
reload_xinerama_infos (screen);
+ set_desktop_geometry_hint (screen);
/* Queue a resize on all the windows */
meta_screen_foreach_window (screen, meta_screen_resize_func, 0);
diff --git a/src/window.c b/src/window.c
index 3421c32..17182eb 100644
--- a/src/window.c
+++ b/src/window.c
@@ -491,6 +491,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
window->wm_state_skip_pager = FALSE;
window->wm_state_above = FALSE;
window->wm_state_below = FALSE;
+ window->wm_state_demands_attention = FALSE;
window->res_class = NULL;
window->res_name = NULL;
@@ -1125,7 +1126,7 @@ static void
set_net_wm_state (MetaWindow *window)
{
int i;
- unsigned long data[10];
+ unsigned long data[11];
i = 0;
if (window->shaded)
@@ -1175,7 +1176,12 @@ set_net_wm_state (MetaWindow *window)
data[i] = window->display->atom_net_wm_state_below;
++i;
}
-
+ if (window->wm_state_demands_attention)
+ {
+ data[i] = window->display->atom_net_wm_state_demands_attention;
+ ++i;
+ }
+
meta_verbose ("Setting _NET_WM_STATE with %d atoms\n", i);
meta_error_trap_push (window->display);
@@ -1810,12 +1816,14 @@ meta_window_show (MetaWindow *window)
meta_window_focus (window,
meta_display_get_current_time (window->display));
}
+ else
+ window->wm_state_demands_attention = TRUE;
}
if (did_show)
{
set_net_wm_state (window);
-
+
if (window->struts)
{
meta_topic (META_DEBUG_WORKAREA,
@@ -3266,7 +3274,7 @@ meta_window_focus (MetaWindow *window,
window->desc);
return;
}
-
+
/* For output-only or shaded windows, focus the frame.
* This seems to result in the client window getting key events
* though, so I don't know if it's icccm-compliant.
@@ -3317,6 +3325,12 @@ meta_window_focus (MetaWindow *window,
meta_error_trap_pop (window->display, FALSE);
}
+
+ if (window->wm_state_demands_attention)
+ {
+ window->wm_state_demands_attention = FALSE;
+ set_net_wm_state (window);
+ }
}
static void
@@ -3956,6 +3970,16 @@ meta_window_client_message (MetaWindow *window,
meta_window_update_layer (window);
set_net_wm_state (window);
}
+
+ if (first == display->atom_net_wm_state_demands_attention ||
+ second == display->atom_net_wm_state_demands_attention)
+ {
+ window->wm_state_demands_attention =
+ (action == _NET_WM_STATE_ADD) ||
+ (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention);
+
+ set_net_wm_state (window);
+ }
return TRUE;
}
@@ -4100,8 +4124,22 @@ meta_window_client_message (MetaWindow *window,
meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s', activating",
window->desc);
- meta_window_activate (window, meta_display_get_current_time (window->display));
-
+ if (event->xclient.data.l[0] != 0)
+ {
+ /* Client supports newer _NET_ACTIVE_WINDOW with a
+ * convenient timestamp
+ */
+ meta_window_activate (window,
+ event->xclient.data.l[1]);
+
+ }
+ else
+ {
+ /* Client using older EWMH _NET_ACTIVE_WINDOW without a
+ * timestamp
+ */
+ meta_window_activate (window, meta_display_get_current_time (window->display));
+ }
return TRUE;
}
@@ -4568,6 +4606,7 @@ update_net_wm_state (MetaWindow *window)
window->wm_state_skip_pager = FALSE;
window->wm_state_above = FALSE;
window->wm_state_below = FALSE;
+ window->wm_state_demands_attention = FALSE;
if (meta_prop_get_atom_list (window->display, window->xwindow,
window->display->atom_net_wm_state,
@@ -4596,6 +4635,8 @@ update_net_wm_state (MetaWindow *window)
window->wm_state_above = TRUE;
else if (atoms[i] == window->display->atom_net_wm_state_below)
window->wm_state_below = TRUE;
+ else if (atoms[i] == window->display->atom_net_wm_state_demands_attention)
+ window->wm_state_demands_attention = TRUE;
++i;
}
diff --git a/src/window.h b/src/window.h
index ca79484..183c58f 100644
--- a/src/window.h
+++ b/src/window.h
@@ -190,6 +190,9 @@ struct _MetaWindow
/* TRUE if client set these */
guint wm_state_above : 1;
guint wm_state_below : 1;
+
+ /* EWHH demands attention flag */
+ guint wm_state_demands_attention : 1;
/* this flag tracks receipt of focus_in focus_out and
* determines whether we draw the focus