diff --git a/ChangeLog b/ChangeLog index 811bbddac..875536bba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2002-08-01 Mark McLoughlin + + Implements support for _NET_WM_ALLOWED_ACTIONS. + Fixes #84282. + + * src/display.[ch]: (meta_display_open): add + _NET_WM_ALLOWED_ACTIONS atoms. + + * src/screen.c: (set_supported_hint): set them + as being supported. + + * src/window.c: + (set_allowed_actions_hint): impl setting + _NET_WM_ALLOWED_ACTIONS. + (recalc_window_features): use it here, but only + if things have changed. + 2002-08-01 Christophe Fergeau * src/metacity-dialog.c: focus the "Close" button by default on diff --git a/src/display.c b/src/display.c index e26eaa7e0..fd4cfd462 100644 --- a/src/display.c +++ b/src/display.c @@ -227,7 +227,16 @@ meta_display_open (const char *name) "TIMESTAMP", "VERSION", "ATOM_PAIR", - "_NET_DESKTOP_NAMES" + "_NET_DESKTOP_NAMES", + "_NET_WM_ALLOWED_ACTIONS", + "_NET_WM_ACTION_MOVE", + "_NET_WM_ACTION_RESIZE", + "_NET_WM_ACTION_SHADE", + "_NET_WM_ACTION_STICK", + "_NET_WM_ACTION_MAXIMIZE_HORZ", + "_NET_WM_ACTION_MAXIMIZE_VERT", + "_NET_WM_ACTION_CHANGE_DESKTOP", + "_NET_WM_ACTION_CLOSE", }; Atom atoms[G_N_ELEMENTS(atom_names)]; @@ -359,6 +368,15 @@ meta_display_open (const char *name) display->atom_version = atoms[63]; display->atom_atom_pair = atoms[64]; display->atom_net_desktop_names = atoms[65]; + display->atom_net_wm_allowed_actions = atoms[66]; + display->atom_net_wm_action_move = atoms[67]; + display->atom_net_wm_action_resize = atoms[68]; + display->atom_net_wm_action_shade = atoms[69]; + display->atom_net_wm_action_stick = atoms[70]; + display->atom_net_wm_action_maximize_horz = atoms[71]; + display->atom_net_wm_action_maximize_vert = atoms[72]; + display->atom_net_wm_action_change_desktop = atoms[73]; + display->atom_net_wm_action_close = atoms[74]; /* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK, * created in screen_new diff --git a/src/display.h b/src/display.h index 33cc05b1c..a16bc5bc3 100644 --- a/src/display.h +++ b/src/display.h @@ -138,6 +138,15 @@ struct _MetaDisplay Atom atom_version; Atom atom_atom_pair; Atom atom_net_desktop_names; + Atom atom_net_wm_allowed_actions; + Atom atom_net_wm_action_move; + Atom atom_net_wm_action_resize; + Atom atom_net_wm_action_shade; + Atom atom_net_wm_action_stick; + Atom atom_net_wm_action_maximize_horz; + Atom atom_net_wm_action_maximize_vert; + Atom atom_net_wm_action_change_desktop; + Atom atom_net_wm_action_close; /* 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 4a5161485..e35ca43fd 100644 --- a/src/screen.c +++ b/src/screen.c @@ -81,7 +81,7 @@ set_wm_check_hint (MetaScreen *screen) static int set_supported_hint (MetaScreen *screen) { -#define N_SUPPORTED 33 +#define N_SUPPORTED 42 #define N_WIN_SUPPORTED 1 Atom atoms[N_SUPPORTED]; @@ -118,6 +118,15 @@ set_supported_hint (MetaScreen *screen) atoms[30] = screen->display->atom_net_show_desktop; atoms[31] = screen->display->atom_net_desktop_layout; atoms[32] = screen->display->atom_net_desktop_names; + atoms[33] = screen->display->atom_net_wm_allowed_actions; + atoms[34] = screen->display->atom_net_wm_action_move; + atoms[35] = screen->display->atom_net_wm_action_resize; + atoms[36] = screen->display->atom_net_wm_action_shade; + atoms[37] = screen->display->atom_net_wm_action_stick; + atoms[38] = screen->display->atom_net_wm_action_maximize_horz; + atoms[39] = screen->display->atom_net_wm_action_maximize_vert; + atoms[40] = screen->display->atom_net_wm_action_change_desktop; + atoms[41] = screen->display->atom_net_wm_action_close; XChangeProperty (screen->display->xdisplay, screen->xroot, screen->display->atom_net_supported, diff --git a/src/window.c b/src/window.c index 585243713..1cc798ef0 100644 --- a/src/window.c +++ b/src/window.c @@ -576,7 +576,7 @@ meta_window_new (MetaDisplay *display, Window xwindow, /* for the various on_all_workspaces = TRUE possible above */ meta_window_set_current_workspace_hint (window); - + /* Put our state back where it should be, * passing TRUE for is_configure_request, ICCCM says * initial map is handled same as configure request @@ -4998,9 +4998,83 @@ recalc_window_type (MetaWindow *window) } } +static int +set_allowed_actions_hint (MetaWindow *window) +{ +#define MAX_N_ACTIONS 8 + unsigned long data[MAX_N_ACTIONS]; + int i; + + + + i = 0; + if (window->has_close_func) + { + data[i] = window->display->atom_net_wm_action_close; + ++i; + } + if (window->has_minimize_func) + { + data[i] = window->display->atom_net_wm_action_maximize_horz; + ++i; + data[i] = window->display->atom_net_wm_action_maximize_vert; + ++i; + } + if (window->has_move_func) + { + data[i] = window->display->atom_net_wm_action_move; + ++i; + } + if (window->has_resize_func) + { + data[i] = window->display->atom_net_wm_action_resize; + ++i; + } + if (window->has_shade_func) + { + data[i] = window->display->atom_net_wm_action_shade; + ++i; + } + if (!window->always_sticky) + { + data[i] = window->display->atom_net_wm_action_stick; + ++i; + } + + /* We always allow this */ + data[i] = window->display->atom_net_wm_action_change_desktop; + ++i; + + g_assert (i <= MAX_N_ACTIONS); + + meta_verbose ("Setting _NET_WM_ALLOWED_ACTIONS with %d atoms\n", i); + + meta_error_trap_push (window->display); + XChangeProperty (window->display->xdisplay, window->xwindow, + window->display->atom_net_wm_allowed_actions, + XA_ATOM, + 32, PropModeReplace, (guchar*) data, i); + return meta_error_trap_pop (window->display); +#undef MAX_N_ACTIONS +} + static void recalc_window_features (MetaWindow *window) { + gboolean old_has_close_func; + gboolean old_has_minimize_func; + gboolean old_has_move_func; + gboolean old_has_resize_func; + gboolean old_has_shade_func; + gboolean old_always_sticky; + + old_has_close_func = window->has_close_func; + old_has_minimize_func = window->has_minimize_func; + old_has_move_func = window->has_move_func; + old_has_resize_func = window->has_resize_func; + old_has_shade_func = window->has_shade_func; + old_always_sticky = window->always_sticky; + /* Use MWM hints initially */ window->decorated = window->mwm_decorated; window->border_only = window->mwm_border_only; @@ -5107,6 +5181,20 @@ recalc_window_features (MetaWindow *window) case META_WINDOW_NORMAL: break; } + + /* FIXME: + * Lame workaround for recalc_window_features + * being used overzealously. The fix is to + * only recalc_window_features when something + * has actually changed. + */ + if (old_has_close_func != window->has_close_func || + old_has_minimize_func != window->has_minimize_func || + old_has_move_func != window->has_move_func || + old_has_resize_func != window->has_resize_func || + old_has_shade_func != window->has_shade_func || + old_always_sticky != window->always_sticky) + set_allowed_actions_hint (window); /* FIXME perhaps should ensure if we don't have a shade func, * we aren't shaded, etc.