use window-props.h stuff for a couple of properties (implement_showing):

2002-11-03  Havoc Pennington  <hp@pobox.com>

	* src/window.c (meta_window_new): use window-props.h stuff for a
	couple of properties
	(implement_showing): fix printf string

	* src/xprops.c (meta_prop_free_values): new function

	* src/window-props.h, src/window-props.c: start moving code that
	handles loading window properties into this file.
This commit is contained in:
Havoc Pennington 2002-11-03 23:42:21 +00:00 committed by Havoc Pennington
parent 1d0b5ef660
commit d7917c02fe
10 changed files with 482 additions and 45 deletions

View File

@ -1,3 +1,19 @@
2002-11-03 Havoc Pennington <hp@pobox.com>
* src/window.c (meta_window_new): use window-props.h stuff for a
couple of properties
(implement_showing): fix printf string
* src/xprops.c (meta_prop_free_values): new function
* src/window-props.h, src/window-props.c: start moving code that
handles loading window properties into this file.
2002-11-03 Havoc Pennington <hp@pobox.com>
* src/stack.c (create_constraints): filter out windows that aren't
in the stack for whatever reason, avoids a crash
2002-11-03 Havoc Pennington <hp@pobox.com>
* src/window.c (meta_window_calc_showing): split into "see if we

View File

@ -72,6 +72,8 @@ metacity_SOURCES= \
util.h \
window.c \
window.h \
window-props.c \
window-props.h \
workspace.c \
workspace.h \
xprops.c \

View File

@ -25,6 +25,7 @@
#include "main.h"
#include "screen.h"
#include "window.h"
#include "window-props.h"
#include "frame.h"
#include "errors.h"
#include "keybindings.h"
@ -383,6 +384,9 @@ meta_display_open (const char *name)
display->atom_net_wm_action_close = atoms[74];
display->atom_net_wm_state_above = atoms[75];
display->atom_net_wm_state_below = atoms[76];
display->prop_hooks = NULL;
meta_display_init_window_prop_hooks (display);
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
* created in screen_new
@ -663,6 +667,8 @@ meta_display_close (MetaDisplay *display)
XDestroyWindow (display->xdisplay, display->leader_window);
XFlush (display->xdisplay);
meta_display_free_window_prop_hooks (display);
#ifndef USE_GDK_DISPLAY
meta_event_queue_free (display->events);

View File

@ -57,6 +57,8 @@ typedef struct _MetaUISlave MetaUISlave;
typedef struct _MetaWindow MetaWindow;
typedef struct _MetaWorkspace MetaWorkspace;
typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
Window xwindow,
gpointer user_data);
@ -262,6 +264,9 @@ struct _MetaDisplay
/* currently-active window menu if any */
MetaWindowMenu *window_menu;
MetaWindow *window_with_menu;
/* Managed by window-props.c */
MetaWindowPropHooks *prop_hooks;
#ifdef HAVE_STARTUP_NOTIFICATION
/* This is at the end in case someone doesn't include config.h before this file
@ -269,7 +274,6 @@ struct _MetaDisplay
*/
SnDisplay *sn_display;
#endif
};
gboolean meta_display_open (const char *name);

View File

@ -522,6 +522,8 @@ add_constraint (Constraint **constraints,
w->transient_parent_is_root_window) && \
WINDOW_HAS_TRANSIENT_TYPE (w))
#define WINDOW_IN_STACK(w) (w->stack_position >= 0)
static void
create_constraints (Constraint **constraints,
GList *windows)
@ -532,6 +534,12 @@ create_constraints (Constraint **constraints,
while (tmp != NULL)
{
MetaWindow *w = tmp->data;
if (!WINDOW_IN_STACK (w))
{
tmp = tmp->next;
continue;
}
if (WINDOW_TRANSIENT_FOR_WHOLE_GROUP (w))
{
@ -552,6 +560,12 @@ create_constraints (Constraint **constraints,
{
MetaWindow *group_window = tmp2->data;
if (!WINDOW_IN_STACK (group_window))
{
tmp2 = tmp2->next;
continue;
}
#if 0
/* old way of doing it */
if (!(meta_window_is_ancestor_of_transient (w, group_window)) &&
@ -581,7 +595,7 @@ create_constraints (Constraint **constraints,
parent =
meta_display_lookup_x_window (w->display, w->xtransient_for);
if (parent)
if (parent && WINDOW_IN_STACK (parent))
{
meta_topic (META_DEBUG_STACK, "Constraining %s above %s due to transiency\n",
w->desc, parent->desc);

328
src/window-props.c Normal file
View File

@ -0,0 +1,328 @@
/* MetaWindow property handling */
/*
* Copyright (C) 2001, 2002 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <config.h>
#include "window-props.h"
#include "xprops.h"
#include <X11/Xatom.h>
typedef void (* InitValueFunc) (MetaDisplay *display,
Atom property,
MetaPropValue *value);
typedef void (* ReloadValueFunc) (MetaWindow *window,
MetaPropValue *value);
struct _MetaWindowPropHooks
{
Atom property;
InitValueFunc init_func;
ReloadValueFunc reload_func;
};
static void init_prop_value (MetaDisplay *display,
Atom property,
MetaPropValue *value);
static void reload_prop_value (MetaWindow *window,
MetaPropValue *value);
static MetaWindowPropHooks* find_hooks (MetaDisplay *display,
Atom property);
void
meta_window_reload_property (MetaWindow *window,
Atom property)
{
meta_window_reload_properties (window, &property, 1);
}
void
meta_window_reload_properties (MetaWindow *window,
const Atom *properties,
int n_properties)
{
int i;
MetaPropValue *values;
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)
{
init_prop_value (window->display, properties[i], &values[i]);
++i;
}
meta_prop_get_values (window->display, window->xwindow,
values, n_properties);
i = 0;
while (i < n_properties)
{
reload_prop_value (window, &values[i]);
++i;
}
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,
Atom property,
MetaPropValue *value)
{
MetaWindowPropHooks *hooks;
hooks = find_hooks (display, property);
g_assert (hooks != NULL);
if (hooks->init_func != NULL)
(* hooks->init_func) (display, property, value);
}
static void
reload_prop_value (MetaWindow *window,
MetaPropValue *value)
{
MetaWindowPropHooks *hooks;
hooks = find_hooks (window->display, value->atom);
g_assert (hooks != NULL);
if (hooks->reload_func != NULL)
(* hooks->reload_func) (window, value);
}
static void
init_wm_client_machine (MetaDisplay *display,
Atom property,
MetaPropValue *value)
{
value->type = META_PROP_VALUE_STRING;
value->atom = display->atom_wm_client_machine;
}
static void
reload_wm_client_machine (MetaWindow *window,
MetaPropValue *value)
{
g_free (window->wm_client_machine);
window->wm_client_machine = NULL;
if (value->type != META_PROP_VALUE_INVALID)
window->wm_client_machine = g_strdup (value->v.str);
meta_verbose ("Window has client machine \"%s\"\n",
window->wm_client_machine ? window->wm_client_machine : "unset");
}
static void
init_net_wm_pid (MetaDisplay *display,
Atom property,
MetaPropValue *value)
{
value->type = META_PROP_VALUE_CARDINAL;
value->atom = display->atom_net_wm_pid;
}
static void
reload_net_wm_pid (MetaWindow *window,
MetaPropValue *value)
{
if (value->type != META_PROP_VALUE_INVALID)
{
gulong cardinal = (int) value->v.cardinal;
if (cardinal <= 0)
meta_warning (_("Application set a bogus _NET_WM_PID %ld\n"),
cardinal);
else
{
window->net_wm_pid = cardinal;
meta_verbose ("Window has _NET_WM_PID %d\n",
window->net_wm_pid);
}
}
}
#define N_HOOKS 22
void
meta_display_init_window_prop_hooks (MetaDisplay *display)
{
int i;
MetaWindowPropHooks *hooks;
g_assert (display->prop_hooks == NULL);
display->prop_hooks = g_new0 (MetaWindowPropHooks, N_HOOKS);
hooks = display->prop_hooks;
i = 0;
hooks[i].property = display->atom_wm_state;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_wm_client_machine;
hooks[i].init_func = init_wm_client_machine;
hooks[i].reload_func = reload_wm_client_machine;
++i;
hooks[i].property = display->atom_net_wm_pid;
hooks[i].init_func = init_net_wm_pid;
hooks[i].reload_func = reload_net_wm_pid;
++i;
hooks[i].property = XA_WM_NORMAL_HINTS;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_net_wm_name;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = XA_WM_NAME;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = XA_WM_HINTS;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_net_wm_state;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_motif_wm_hints;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_net_wm_icon_geometry;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = XA_WM_CLASS;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_wm_client_leader;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_sm_client_id;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_wm_window_role;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_net_wm_window_type;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_win_layer;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_net_wm_desktop;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_win_workspace;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_net_wm_icon_name;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = XA_WM_ICON_NAME;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_net_wm_strut;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
hooks[i].property = display->atom_win_hints;
hooks[i].init_func = NULL;
hooks[i].reload_func = NULL;
++i;
if (i != N_HOOKS)
g_error ("Initialized %d hooks should have been %d\n", i, N_HOOKS);
}
void
meta_display_free_window_prop_hooks (MetaDisplay *display)
{
g_assert (display->prop_hooks != NULL);
g_free (display->prop_hooks);
display->prop_hooks = NULL;
}
static MetaWindowPropHooks*
find_hooks (MetaDisplay *display,
Atom property)
{
int i;
/* FIXME we could sort the array and do binary search or
* something
*/
i = 0;
while (i < N_HOOKS)
{
if (display->prop_hooks[i].property == property)
return &display->prop_hooks[i];
++i;
}
return NULL;
}

36
src/window-props.h Normal file
View File

@ -0,0 +1,36 @@
/* MetaWindow property handling */
/*
* Copyright (C) 2001, 2002 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_WINDOW_PROPS_H
#define META_WINDOW_PROPS_H
#include "window.h"
void meta_window_reload_property (MetaWindow *window,
Atom property);
void meta_window_reload_properties (MetaWindow *window,
const Atom *properties,
int n_properties);
void meta_display_init_window_prop_hooks (MetaDisplay *display);
void meta_display_free_window_prop_hooks (MetaDisplay *display);
#endif /* META_WINDOW_PROPS_H */

View File

@ -36,6 +36,7 @@
#include "resizepopup.h"
#include "xprops.h"
#include "group.h"
#include "window-props.h"
#include <X11/Xatom.h>
#include <string.h>
@ -160,19 +161,9 @@ meta_window_new (MetaDisplay *display,
MetaWorkspace *space;
gulong existing_wm_state;
#define N_INITIAL_PROPS 2
MetaPropValue initial_props[N_INITIAL_PROPS];
Atom initial_props[N_INITIAL_PROPS];
g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props));
memset (initial_props, '\0', sizeof (initial_props));
#define INITIAL_PROP_WM_CLIENT_MACHINE 0
initial_props[0].type = META_PROP_VALUE_STRING;
initial_props[0].atom = display->atom_wm_client_machine;
#define INITIAL_PROP_NET_WM_PID 1
initial_props[1].type = META_PROP_VALUE_CARDINAL;
initial_props[1].atom = display->atom_net_wm_pid;
meta_verbose ("Attempting to manage 0x%lx\n", xwindow);
@ -436,37 +427,13 @@ meta_window_new (MetaDisplay *display,
window->stack_position = -1;
window->initial_workspace = 0; /* not used */
meta_display_register_x_window (display, &window->xwindow, window);
meta_prop_get_values (display, window->xwindow,
initial_props, N_INITIAL_PROPS);
if (initial_props[INITIAL_PROP_WM_CLIENT_MACHINE].type !=
META_PROP_VALUE_INVALID)
{
window->wm_client_machine =
g_strdup (initial_props[INITIAL_PROP_WM_CLIENT_MACHINE].v.str);
meta_XFree (initial_props[INITIAL_PROP_WM_CLIENT_MACHINE].v.str);
meta_verbose ("Window has client machine \"%s\"\n",
window->wm_client_machine);
}
if (initial_props[INITIAL_PROP_NET_WM_PID].type !=
META_PROP_VALUE_INVALID)
{
gulong cardinal = (int) initial_props[INITIAL_PROP_NET_WM_PID].v.cardinal;
if (cardinal <= 0)
meta_warning (_("Application set a bogus _NET_WM_PID %ld\n"),
cardinal);
else
{
window->net_wm_pid = cardinal;
meta_verbose ("Window has _NET_WM_PID %d\n",
window->net_wm_pid);
}
}
/* Fill these in the order we want them to be gotten */
initial_props[0] = display->atom_wm_client_machine;
initial_props[1] = display->atom_net_wm_pid;
g_assert (N_INITIAL_PROPS == 2);
meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS);
update_size_hints (window);
update_title (window);
@ -1187,8 +1154,8 @@ implement_showing (MetaWindow *window,
gboolean showing)
{
/* Actually show/hide the window */
meta_verbose ("Implement showing = %d for window %s\n", window->desc,
showing);
meta_verbose ("Implement showing = %d for window %s\n",
showing, window->desc);
if (!showing)
{

View File

@ -1042,3 +1042,64 @@ meta_prop_get_values (MetaDisplay *display,
g_free (tasks);
}
static void
free_value (MetaPropValue *value)
{
switch (value->type)
{
case META_PROP_VALUE_INVALID:
break;
case META_PROP_VALUE_UTF8:
meta_XFree (value->v.str);
break;
case META_PROP_VALUE_STRING:
meta_XFree (value->v.str);
break;
case META_PROP_VALUE_MOTIF_HINTS:
meta_XFree (value->v.motif_hints);
break;
case META_PROP_VALUE_CARDINAL:
break;
case META_PROP_VALUE_WINDOW:
break;
case META_PROP_VALUE_ATOM_LIST:
meta_XFree (value->v.atom_list.atoms);
break;
case META_PROP_VALUE_TEXT_PROPERTY:
meta_XFree (value->v.str);
break;
case META_PROP_VALUE_WM_HINTS:
meta_XFree (value->v.wm_hints);
break;
case META_PROP_VALUE_CLASS_HINT:
meta_XFree (value->v.class_hint.res_class);
meta_XFree (value->v.class_hint.res_name);
break;
case META_PROP_VALUE_SIZE_HINTS:
meta_XFree (value->v.size_hints.hints);
break;
case META_PROP_VALUE_UTF8_LIST:
g_strfreev (value->v.string_list.strings);
break;
case META_PROP_VALUE_CARDINAL_LIST:
meta_XFree (value->v.cardinal_list.cardinals);
break;
}
}
void
meta_prop_free_values (MetaPropValue *values,
int n_values)
{
int i;
i = 0;
while (i < n_values)
{
free_value (&values[i]);
++i;
}
/* Zero the whole thing to quickly detect breakage */
memset (values, '\0', sizeof (MetaPropValue) * n_values);
}

View File

@ -199,6 +199,9 @@ void meta_prop_get_values (MetaDisplay *display,
MetaPropValue *values,
int n_values);
void meta_prop_free_values (MetaPropValue *values,
int n_values);
#endif