diff options
author | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2014-10-05 02:44:11 +0300 |
---|---|---|
committer | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2014-10-05 02:44:11 +0300 |
commit | a91fda7881f6b038abd8f2a27e326811da6e0b65 (patch) | |
tree | ca2bd39c9914cdc0a5fef8f8c45253913c9a6388 | |
parent | 49552340d5b55ffc535ded300a36f6d736b70501 (diff) | |
download | metacity-a91fda7881f6b038abd8f2a27e326811da6e0b65.tar.gz |
window-props: improve properties handling
All changes here are based on mutter.
-rw-r--r-- | src/core/display-private.h | 4 | ||||
-rw-r--r-- | src/core/window-private.h | 3 | ||||
-rw-r--r-- | src/core/window-props.c | 384 | ||||
-rw-r--r-- | src/core/window-props.h | 39 | ||||
-rw-r--r-- | src/core/window.c | 121 |
5 files changed, 313 insertions, 238 deletions
diff --git a/src/core/display-private.h b/src/core/display-private.h index 31cc9280..f98db283 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -50,6 +50,7 @@ typedef struct _MetaUISlave MetaUISlave; typedef struct _MetaWorkspace MetaWorkspace; typedef struct _MetaGroupPropHooks MetaGroupPropHooks; +typedef struct _MetaWindowPropHooks MetaWindowPropHooks; typedef struct MetaEdgeResistanceData MetaEdgeResistanceData; @@ -242,8 +243,9 @@ struct _MetaDisplay MetaWindow *window_with_menu; /* Managed by window-props.c */ - gpointer *prop_hooks_table; + MetaWindowPropHooks *prop_hooks_table; GHashTable *prop_hooks; + int n_prop_hooks; /* Managed by group-props.c */ MetaGroupPropHooks *group_prop_hooks; diff --git a/src/core/window-private.h b/src/core/window-private.h index 78bbafb4..875ccdf4 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -655,9 +655,6 @@ void meta_window_unset_demands_attention (MetaWindow *window); void meta_window_update_icon_now (MetaWindow *window); -void meta_window_update_role (MetaWindow *window); -void meta_window_update_net_wm_type (MetaWindow *window); - gboolean meta_window_can_tile_side_by_side (MetaWindow *window); #endif diff --git a/src/core/window-props.c b/src/core/window-props.c index d49d21e6..462dbb81 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -64,14 +64,21 @@ typedef void (* ReloadValueFunc) (MetaWindow *window, MetaPropValue *value, gboolean initial); -typedef struct MetaWindowPropHooks -{ +typedef enum { + NONE = 0, + LOAD_INIT = (1 << 0), + INIT_ONLY = (1 << 1), + FORCE_INIT = (1 << 2), +} MetaPropHookFlags; + +struct _MetaWindowPropHooks { Atom property; MetaPropValueType type; ReloadValueFunc reload_func; -} MetaWindowPropHooks; + MetaPropHookFlags flags; +}; -static void init_prop_value (MetaDisplay *display, +static void init_prop_value (MetaWindow *window, MetaWindowPropHooks *hooks, MetaPropValue *value); static void reload_prop_value (MetaWindow *window, @@ -81,81 +88,89 @@ static void reload_prop_value (MetaWindow *window, static MetaWindowPropHooks* find_hooks (MetaDisplay *display, Atom property); - void -meta_window_reload_property (MetaWindow *window, - Atom property, - gboolean initial) +meta_window_reload_property_from_xwindow (MetaWindow *window, + Window xwindow, + Atom property, + gboolean initial) { - meta_window_reload_properties (window, &property, 1, initial); -} + MetaPropValue value = { 0, }; + MetaWindowPropHooks *hooks; -void -meta_window_reload_properties (MetaWindow *window, - const Atom *properties, - int n_properties, - gboolean initial) -{ - meta_window_reload_properties_from_xwindow (window, - window->xwindow, - properties, - n_properties, - initial); + hooks = find_hooks (window->display, property); + if (!hooks) + return; + + init_prop_value (window, hooks, &value); + + meta_prop_get_values (window->display, xwindow, + &value, 1); + + reload_prop_value (window, hooks, &value, + initial); + + meta_prop_free_values (&value, 1); } void -meta_window_reload_property_from_xwindow (MetaWindow *window, - Window xwindow, - Atom property, - gboolean initial) +meta_window_reload_property (MetaWindow *window, + Atom property, + gboolean initial) { - meta_window_reload_properties_from_xwindow (window, xwindow, &property, 1, - initial); + meta_window_reload_property_from_xwindow (window, + window->xwindow, + property, + initial); } void -meta_window_reload_properties_from_xwindow (MetaWindow *window, - Window xwindow, - const Atom *properties, - int n_properties, - gboolean initial) +meta_window_load_initial_properties (MetaWindow *window) { - int i; + int i, j; MetaPropValue *values; + int n_properties = 0; - g_return_if_fail (properties != NULL); - g_return_if_fail (n_properties > 0); - - values = g_new0 (MetaPropValue, n_properties); - - i = 0; - while (i < n_properties) + values = g_new0 (MetaPropValue, window->display->n_prop_hooks); + + j = 0; + for (i = 0; i < window->display->n_prop_hooks; i++) { - MetaWindowPropHooks *hooks = find_hooks (window->display, properties[i]); - init_prop_value (window->display, hooks, &values[i]); - ++i; + MetaWindowPropHooks *hooks = &window->display->prop_hooks_table[i]; + if (hooks->flags & LOAD_INIT) + { + init_prop_value (window, hooks, &values[j]); + ++j; + } } - - meta_prop_get_values (window->display, xwindow, + n_properties = j; + + meta_prop_get_values (window->display, window->xwindow, values, n_properties); - i = 0; - while (i < n_properties) + j = 0; + for (i = 0; i < window->display->n_prop_hooks; i++) { - MetaWindowPropHooks *hooks = find_hooks (window->display, properties[i]); - reload_prop_value (window, hooks, &values[i], initial); - - ++i; + MetaWindowPropHooks *hooks = &window->display->prop_hooks_table[i]; + if (hooks->flags & LOAD_INIT) + { + /* If we didn't actually manage to load anything then we don't need + * to call the reload function; this is different from a notification + * where disappearance of a previously present value is significant. + */ + if (values[j].type != META_PROP_VALUE_INVALID || hooks->flags & FORCE_INIT) + reload_prop_value (window, hooks, &values[j], TRUE); + ++j; + } } meta_prop_free_values (values, n_properties); - + g_free (values); } /* Fill in the MetaPropValue used to get the value of "property" */ static void -init_prop_value (MetaDisplay *display, +init_prop_value (MetaWindow *window, MetaWindowPropHooks *hooks, MetaPropValue *value) { @@ -210,7 +225,62 @@ reload_net_wm_window_type (MetaWindow *window, MetaPropValue *value, gboolean initial) { - meta_window_update_net_wm_type (window); + int n_atoms; + Atom *atoms; + int i; + + window->type_atom = None; + n_atoms = 0; + atoms = NULL; + + meta_prop_get_atom_list (window->display, window->xwindow, + window->display->atom__NET_WM_WINDOW_TYPE, + &atoms, &n_atoms); + + i = 0; + while (i < n_atoms) + { + /* We break as soon as we find one we recognize, + * supposed to prefer those near the front of the list + */ + if (atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DOCK || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_MENU || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY || + atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH) + { + window->type_atom = atoms[i]; + break; + } + + ++i; + } + + meta_XFree (atoms); + + if (meta_is_verbose ()) + { + char *str; + + str = NULL; + if (window->type_atom != None) + { + meta_error_trap_push (window->display); + str = XGetAtomName (window->display->xdisplay, window->type_atom); + meta_error_trap_pop (window->display, TRUE); + } + + meta_verbose ("Window %s type atom %s\n", window->desc, + str ? str : "(none)"); + + if (str) + meta_XFree (str); + } + + meta_window_recalc_window_type (window); } static void @@ -252,7 +322,9 @@ reload_wm_window_role (MetaWindow *window, MetaPropValue *value, gboolean initial) { - meta_window_update_role (window); + g_clear_pointer (&window->role, g_free); + if (value->type != META_PROP_VALUE_INVALID) + window->role = g_strdup (value->v.str); } static void @@ -701,6 +773,7 @@ reload_net_wm_state (MetaWindow *window, window->desc); meta_window_recalc_window_type (window); + meta_window_recalc_features (window); } static void @@ -1510,35 +1583,171 @@ void meta_display_init_window_prop_hooks (MetaDisplay *display) { MetaWindowPropHooks hooks[] = { - { display->atom_WM_STATE, META_PROP_VALUE_INVALID, NULL }, - { display->atom_WM_CLIENT_MACHINE, META_PROP_VALUE_STRING, reload_wm_client_machine }, - { display->atom__NET_WM_PID, META_PROP_VALUE_CARDINAL, reload_net_wm_pid }, - { display->atom__NET_WM_USER_TIME, META_PROP_VALUE_CARDINAL, reload_net_wm_user_time }, - { display->atom__NET_WM_NAME, META_PROP_VALUE_UTF8, reload_net_wm_name }, - { XA_WM_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_name }, - { display->atom__NET_WM_ICON, META_PROP_VALUE_INVALID, reload_net_wm_icon }, - { display->atom__KWM_WIN_ICON, META_PROP_VALUE_INVALID, reload_kwm_win_icon }, - { display->atom__NET_WM_ICON_NAME, META_PROP_VALUE_UTF8, reload_net_wm_icon_name }, - { XA_WM_ICON_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_icon_name }, - { display->atom__NET_WM_STATE, META_PROP_VALUE_ATOM_LIST, reload_net_wm_state }, - { display->atom__MOTIF_WM_HINTS, META_PROP_VALUE_MOTIF_HINTS, reload_mwm_hints }, - { display->atom__NET_WM_ICON_GEOMETRY, META_PROP_VALUE_INVALID, NULL }, - { XA_WM_CLASS, META_PROP_VALUE_CLASS_HINT, reload_wm_class }, - { display->atom_WM_CLIENT_LEADER, META_PROP_VALUE_INVALID, complain_about_broken_client }, - { display->atom_SM_CLIENT_ID, META_PROP_VALUE_INVALID, complain_about_broken_client }, - { display->atom_WM_WINDOW_ROLE, META_PROP_VALUE_INVALID, reload_wm_window_role }, - { display->atom__NET_WM_WINDOW_TYPE, META_PROP_VALUE_INVALID, reload_net_wm_window_type }, - { display->atom__NET_WM_DESKTOP, META_PROP_VALUE_CARDINAL, reload_net_wm_desktop }, - { display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts }, - { display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts }, - { display->atom__NET_STARTUP_ID, META_PROP_VALUE_UTF8, reload_net_startup_id }, - { display->atom__NET_WM_SYNC_REQUEST_COUNTER, META_PROP_VALUE_SYNC_COUNTER, reload_update_counter }, - { XA_WM_NORMAL_HINTS, META_PROP_VALUE_SIZE_HINTS, reload_normal_hints }, - { display->atom_WM_PROTOCOLS, META_PROP_VALUE_ATOM_LIST, reload_wm_protocols }, - { XA_WM_HINTS, META_PROP_VALUE_WM_HINTS, reload_wm_hints }, - { XA_WM_TRANSIENT_FOR, META_PROP_VALUE_WINDOW, reload_transient_for }, - { display->atom__NET_WM_USER_TIME_WINDOW, META_PROP_VALUE_WINDOW, reload_net_wm_user_time_window }, - { 0 }, + { + display->atom_WM_CLIENT_MACHINE, + META_PROP_VALUE_STRING, + reload_wm_client_machine, + LOAD_INIT + }, + { + display->atom__NET_WM_NAME, + META_PROP_VALUE_UTF8, + reload_net_wm_name, + LOAD_INIT + }, + { + XA_WM_CLASS, + META_PROP_VALUE_CLASS_HINT, + reload_wm_class, + LOAD_INIT + }, + { + display->atom__NET_WM_PID, + META_PROP_VALUE_CARDINAL, + reload_net_wm_pid, + LOAD_INIT + }, + { + XA_WM_NAME, + META_PROP_VALUE_TEXT_PROPERTY, + reload_wm_name, + LOAD_INIT + }, + { + display->atom__NET_WM_ICON_NAME, + META_PROP_VALUE_UTF8, + reload_net_wm_icon_name, + LOAD_INIT + }, + { + XA_WM_ICON_NAME, + META_PROP_VALUE_TEXT_PROPERTY, + reload_wm_icon_name, + LOAD_INIT + }, + { + display->atom__NET_WM_DESKTOP, + META_PROP_VALUE_CARDINAL, + reload_net_wm_desktop, + LOAD_INIT | INIT_ONLY + }, + { + display->atom__NET_STARTUP_ID, + META_PROP_VALUE_UTF8, + reload_net_startup_id, + LOAD_INIT + }, + { + display->atom__NET_WM_SYNC_REQUEST_COUNTER, + META_PROP_VALUE_SYNC_COUNTER, + reload_update_counter, + LOAD_INIT + }, + { + XA_WM_NORMAL_HINTS, + META_PROP_VALUE_SIZE_HINTS, + reload_normal_hints, + LOAD_INIT + }, + { + display->atom_WM_PROTOCOLS, + META_PROP_VALUE_ATOM_LIST, + reload_wm_protocols, + LOAD_INIT + }, + { + XA_WM_HINTS, + META_PROP_VALUE_WM_HINTS, + reload_wm_hints, + LOAD_INIT + }, + { + display->atom__NET_WM_USER_TIME, + META_PROP_VALUE_CARDINAL, + reload_net_wm_user_time, + LOAD_INIT + }, + { + display->atom__NET_WM_STATE, + META_PROP_VALUE_ATOM_LIST, + reload_net_wm_state, + LOAD_INIT | INIT_ONLY + }, + { + display->atom__MOTIF_WM_HINTS, + META_PROP_VALUE_MOTIF_HINTS, + reload_mwm_hints, + LOAD_INIT + }, + { + XA_WM_TRANSIENT_FOR, + META_PROP_VALUE_WINDOW, + reload_transient_for, + LOAD_INIT + }, + { + display->atom__NET_WM_USER_TIME_WINDOW, + META_PROP_VALUE_WINDOW, + reload_net_wm_user_time_window, + LOAD_INIT + }, + { + display->atom_WM_STATE, + META_PROP_VALUE_INVALID, + NULL, + NONE + }, + { + display->atom__NET_WM_ICON, + META_PROP_VALUE_INVALID, + reload_net_wm_icon, + NONE + }, + { + display->atom__KWM_WIN_ICON, + META_PROP_VALUE_INVALID, + reload_kwm_win_icon, + NONE + }, + { + display->atom_WM_CLIENT_LEADER, + META_PROP_VALUE_INVALID, + complain_about_broken_client, + NONE + }, + { + display->atom_SM_CLIENT_ID, + META_PROP_VALUE_INVALID, + complain_about_broken_client, + NONE + }, + { + display->atom_WM_WINDOW_ROLE, + META_PROP_VALUE_STRING, + reload_wm_window_role, + LOAD_INIT | FORCE_INIT + }, + { + display->atom__NET_WM_WINDOW_TYPE, + META_PROP_VALUE_ATOM_LIST, + reload_net_wm_window_type, + LOAD_INIT | FORCE_INIT + }, + { + display->atom__NET_WM_STRUT, + META_PROP_VALUE_INVALID, + reload_struts, + NONE + }, + { + display->atom__NET_WM_STRUT_PARTIAL, + META_PROP_VALUE_INVALID, + reload_struts, + NONE + }, + { + 0 + }, }; MetaWindowPropHooks *table = g_memdup (hooks, sizeof (hooks)), @@ -1551,6 +1760,12 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) while (cursor->property) { + /* Doing initial loading doesn't make sense if we just want notification */ + g_assert (!((cursor->flags & LOAD_INIT) && cursor->type == META_PROP_VALUE_INVALID)); + + /* Forcing initialization doesn't make sense if not loading initially */ + g_assert ((cursor->flags & LOAD_INIT) || !(cursor->flags & FORCE_INIT)); + /* Atoms are safe to use with GINT_TO_POINTER because it's safe with * anything 32 bits or less, and atoms are 32 bits with the top three * bits clear. (Scheifler & Gettys, 2e, p372) @@ -1560,6 +1775,7 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) cursor); cursor++; } + display->n_prop_hooks = cursor - table; } void diff --git a/src/core/window-props.h b/src/core/window-props.h index 50b615c4..9adaafc2 100644 --- a/src/core/window-props.h +++ b/src/core/window-props.h @@ -44,21 +44,6 @@ void meta_window_reload_property (MetaWindow *window, Atom property, gboolean initial); - -/** - * Requests the current values of a set of properties for a given - * window from the server, and deals with them appropriately. - * Does not return them to the caller (they've been dealt with!) - * - * \param window The window. - * \param properties A pointer to a list of X atoms, "n_properties" long. - * \param n_properties The length of the properties list. - */ -void meta_window_reload_properties (MetaWindow *window, - const Atom *properties, - int n_properties, - gboolean initial); - /** * Requests the current values of a single property for a given * window from the server, and deals with it appropriately. @@ -69,29 +54,19 @@ void meta_window_reload_properties (MetaWindow *window, * \param xwindow The X handle for the window. * \param property A single X atom. */ -void meta_window_reload_property_from_xwindow - (MetaWindow *window, - Window xwindow, - Atom property, - gboolean initial); +void meta_window_reload_property_from_xwindow (MetaWindow *window, + Window xwindow, + Atom property, + gboolean initial); /** - * Requests the current values of a set of properties for a given + * Requests the current values for standard properties for a given * window from the server, and deals with them appropriately. * Does not return them to the caller (they've been dealt with!) * - * \param window A window on the same display as the one we're - * investigating (only used to find the display) - * \param xwindow The X handle for the window. - * \param properties A pointer to a list of X atoms, "n_properties" long. - * \param n_properties The length of the properties list. + * \param window The window. */ -void meta_window_reload_properties_from_xwindow - (MetaWindow *window, - Window xwindow, - const Atom *properties, - int n_properties, - gboolean initial); +void meta_window_load_initial_properties (MetaWindow *window); /** * Initialises the hooks used for the reload_propert* functions diff --git a/src/core/window.c b/src/core/window.c index 578d022f..cfb4deb0 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -252,13 +252,9 @@ meta_window_new_with_attrs (MetaDisplay *display, gulong existing_wm_state; gulong event_mask; MetaMoveResizeFlags flags; -#define N_INITIAL_PROPS 19 - Atom initial_props[N_INITIAL_PROPS]; - int i; gboolean has_shape; g_assert (attrs != NULL); - g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props)); meta_verbose ("Attempting to manage 0x%lx\n", xwindow); @@ -572,39 +568,10 @@ meta_window_new_with_attrs (MetaDisplay *display, window->group = NULL; window->xgroup_leader = None; meta_window_compute_group (window); - - /* Fill these in the order we want them to be gotten. we want to - * get window name and class first so we can use them in error - * messages and such. However, name is modified depending on - * wm_client_machine, so push it slightly sooner. - */ - i = 0; - initial_props[i++] = display->atom_WM_CLIENT_MACHINE; - initial_props[i++] = display->atom__NET_WM_PID; - initial_props[i++] = display->atom__NET_WM_NAME; - initial_props[i++] = XA_WM_CLASS; - initial_props[i++] = XA_WM_NAME; - initial_props[i++] = display->atom__NET_WM_ICON_NAME; - initial_props[i++] = XA_WM_ICON_NAME; - initial_props[i++] = display->atom__NET_WM_DESKTOP; - initial_props[i++] = display->atom__NET_STARTUP_ID; - initial_props[i++] = display->atom__NET_WM_SYNC_REQUEST_COUNTER; - initial_props[i++] = XA_WM_NORMAL_HINTS; - initial_props[i++] = display->atom_WM_PROTOCOLS; - initial_props[i++] = XA_WM_HINTS; - initial_props[i++] = display->atom__NET_WM_USER_TIME; - initial_props[i++] = display->atom__NET_WM_STATE; - initial_props[i++] = display->atom__MOTIF_WM_HINTS; - initial_props[i++] = XA_WM_TRANSIENT_FOR; - initial_props[i++] = display->atom__NET_WM_USER_TIME_WINDOW; - initial_props[i++] = display->atom__NET_WM_FULLSCREEN_MONITORS; - g_assert (N_INITIAL_PROPS == i); - - meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS, TRUE); - + + meta_window_load_initial_properties (window); + update_sm_hints (window); /* must come after transient_for */ - meta_window_update_role (window); - meta_window_update_net_wm_type (window); meta_window_update_icon_now (window); if (window->initially_iconic) @@ -5821,88 +5788,6 @@ update_sm_hints (MetaWindow *window) window->sm_client_id ? window->sm_client_id : "none"); } -void -meta_window_update_role (MetaWindow *window) -{ - char *str; - - if (window->role) - g_free (window->role); - window->role = NULL; - - if (meta_prop_get_latin1_string (window->display, window->xwindow, - window->display->atom_WM_WINDOW_ROLE, - &str)) - { - window->role = g_strdup (str); - meta_XFree (str); - } - - meta_verbose ("Updated role of %s to '%s'\n", - window->desc, window->role ? window->role : "null"); -} - -void -meta_window_update_net_wm_type (MetaWindow *window) -{ - int n_atoms; - Atom *atoms; - int i; - - window->type_atom = None; - n_atoms = 0; - atoms = NULL; - - meta_prop_get_atom_list (window->display, window->xwindow, - window->display->atom__NET_WM_WINDOW_TYPE, - &atoms, &n_atoms); - - i = 0; - while (i < n_atoms) - { - /* We break as soon as we find one we recognize, - * supposed to prefer those near the front of the list - */ - if (atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DOCK || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_MENU || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH) - { - window->type_atom = atoms[i]; - break; - } - - ++i; - } - - meta_XFree (atoms); - - if (meta_is_verbose ()) - { - char *str; - - str = NULL; - if (window->type_atom != None) - { - meta_error_trap_push (window->display); - str = XGetAtomName (window->display->xdisplay, window->type_atom); - meta_error_trap_pop (window->display, TRUE); - } - - meta_verbose ("Window %s type atom %s\n", window->desc, - str ? str : "(none)"); - - if (str) - meta_XFree (str); - } - - meta_window_recalc_window_type (window); -} - static void redraw_icon (MetaWindow *window) { |