diff --git a/ChangeLog b/ChangeLog index 0db6a5244..de854b4b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2002-01-03 Havoc Pennington + + * src/window.c (update_net_wm_state): clean up using + meta_prop_get_atom_list + (update_mwm_hints): clean up using meta_prop_get_motif_hints + + * src/Makefile.am (metacity_SOURCES): add xprops.[hc] + + * src/xprops.c: new file with convenience functions for X + properties + 2002-01-03 Havoc Pennington * src/workspace.c (meta_workspace_activate): focus top window when diff --git a/src/Makefile.am b/src/Makefile.am index 0e2f9cf23..5e79e91e9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -47,7 +47,9 @@ metacity_SOURCES= \ window.c \ window.h \ workspace.c \ - workspace.h + workspace.h \ + xprops.c \ + xprops.h bin_PROGRAMS=metacity diff --git a/src/window.c b/src/window.c index 4d04a3120..25751a5ba 100644 --- a/src/window.c +++ b/src/window.c @@ -32,6 +32,7 @@ #include "session.h" #include "effects.h" #include "prefs.h" +#include "xprops.h" #include @@ -59,8 +60,8 @@ static int update_size_hints (MetaWindow *window); static int update_title (MetaWindow *window); static int update_protocols (MetaWindow *window); static int update_wm_hints (MetaWindow *window); -static int update_net_wm_state (MetaWindow *window); -static int update_mwm_hints (MetaWindow *window); +static void update_net_wm_state (MetaWindow *window); +static void update_mwm_hints (MetaWindow *window); static int update_wm_class (MetaWindow *window); static int update_transient_for (MetaWindow *window); static void update_sm_hints (MetaWindow *window); @@ -3248,116 +3249,52 @@ update_wm_hints (MetaWindow *window) return meta_error_trap_pop (window->display); } -static int +static void update_net_wm_state (MetaWindow *window) { /* We know this is only on initial window creation, * clients don't change the property. */ - Atom type; - int format; - gulong n_atoms; - gulong bytes_after; + + int n_atoms; Atom *atoms; - int result; - int i; window->shaded = FALSE; window->maximized = FALSE; window->wm_state_modal = FALSE; - - meta_error_trap_push (window->display); - XGetWindowProperty (window->display->xdisplay, window->xwindow, - window->display->atom_net_wm_state, - 0, G_MAXLONG, - False, XA_ATOM, &type, &format, &n_atoms, - &bytes_after, (guchar **)&atoms); - result = meta_error_trap_pop (window->display); - if (result != Success) + if (meta_prop_get_atom_list (window->display, window->xwindow, + window->display->atom_net_wm_state, + &atoms, &n_atoms)) { - recalc_window_type (window); - return result; - } - - if (type != XA_ATOM) - { - recalc_window_type (window); - return -1; /* whatever */ - } - - i = 0; - while (i < n_atoms) - { - if (atoms[i] == window->display->atom_net_wm_state_shaded) - window->shaded = TRUE; - else if (atoms[i] == window->display->atom_net_wm_state_maximized_horz) - window->maximized = TRUE; - else if (atoms[i] == window->display->atom_net_wm_state_maximized_vert) - window->maximized = TRUE; - else if (atoms[i] == window->display->atom_net_wm_state_modal) - window->wm_state_modal = TRUE; + int i; - ++i; + i = 0; + while (i < n_atoms) + { + if (atoms[i] == window->display->atom_net_wm_state_shaded) + window->shaded = TRUE; + else if (atoms[i] == window->display->atom_net_wm_state_maximized_horz) + window->maximized = TRUE; + else if (atoms[i] == window->display->atom_net_wm_state_maximized_vert) + window->maximized = TRUE; + else if (atoms[i] == window->display->atom_net_wm_state_modal) + window->wm_state_modal = TRUE; + + ++i; + } + + XFree (atoms); } - XFree (atoms); - recalc_window_type (window); - - return Success; } -/* I don't know of any docs anywhere on what the - * hell most of this means. Copied from Lesstif by - * way of GTK - */ -typedef struct { - unsigned long flags; - unsigned long functions; - unsigned long decorations; - long input_mode; - unsigned long status; -} MotifWmHints, MwmHints; - -#define MWM_HINTS_FUNCTIONS (1L << 0) -#define MWM_HINTS_DECORATIONS (1L << 1) -#define MWM_HINTS_INPUT_MODE (1L << 2) -#define MWM_HINTS_STATUS (1L << 3) - -#define MWM_FUNC_ALL (1L << 0) -#define MWM_FUNC_RESIZE (1L << 1) -#define MWM_FUNC_MOVE (1L << 2) -#define MWM_FUNC_MINIMIZE (1L << 3) -#define MWM_FUNC_MAXIMIZE (1L << 4) -#define MWM_FUNC_CLOSE (1L << 5) - -#define MWM_DECOR_ALL (1L << 0) -#define MWM_DECOR_BORDER (1L << 1) -#define MWM_DECOR_RESIZEH (1L << 2) -#define MWM_DECOR_TITLE (1L << 3) -#define MWM_DECOR_MENU (1L << 4) -#define MWM_DECOR_MINIMIZE (1L << 5) -#define MWM_DECOR_MAXIMIZE (1L << 6) - -#define MWM_INPUT_MODELESS 0 -#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 -#define MWM_INPUT_SYSTEM_MODAL 2 -#define MWM_INPUT_FULL_APPLICATION_MODAL 3 -#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL - -#define MWM_TEAROFF_WINDOW (1L<<0) - -static int +static void update_mwm_hints (MetaWindow *window) { MotifWmHints *hints; - Atom type; - int format; - gulong nitems; - gulong bytes_after; - int result; window->mwm_decorated = TRUE; window->mwm_has_close_func = TRUE; @@ -3365,25 +3302,16 @@ update_mwm_hints (MetaWindow *window) window->mwm_has_maximize_func = TRUE; window->mwm_has_move_func = TRUE; window->mwm_has_resize_func = TRUE; - - meta_error_trap_push (window->display); - XGetWindowProperty (window->display->xdisplay, window->xwindow, - window->display->atom_motif_wm_hints, - 0, sizeof (MotifWmHints)/sizeof (long), - False, AnyPropertyType, &type, &format, &nitems, - &bytes_after, (guchar **)&hints); - result = meta_error_trap_pop (window->display); - - if (result != Success || - type == None) + if (!meta_prop_get_motif_hints (window->display, window->xwindow, + window->display->atom_motif_wm_hints, + &hints)) { meta_verbose ("Window %s has no MWM hints\n", window->desc); - /* may be Success, unused anyhow */ - return result; + return; } - /* We support MWM hints deemed non-stupid */ + /* We support those MWM hints deemed non-stupid */ meta_verbose ("Window %s has MWM hints\n", window->desc); @@ -3467,52 +3395,42 @@ update_mwm_hints (MetaWindow *window) XFree (hints); recalc_window_features (window); - - return Success; } static gboolean meta_window_get_icon_geometry (MetaWindow *window, MetaRectangle *rect) { - Atom type; - int format; - gulong nitems; - gulong bytes_after; - gulong *geometry; - int result; - - meta_error_trap_push (window->display); - type = None; - XGetWindowProperty (window->display->xdisplay, - window->xwindow, - window->display->atom_net_wm_icon_geometry, - 0, G_MAXLONG, - False, XA_CARDINAL, &type, &format, &nitems, - &bytes_after, ((guchar **)&geometry)); - - result = meta_error_trap_pop (window->display); - - if (result != Success || type != XA_CARDINAL) - return FALSE; + gulong *geometry = NULL; + int nitems; - if (nitems != 4) + if (meta_prop_get_cardinal_list (window->display, + window->xwindow, + window->display->atom_net_wm_icon_geometry, + &geometry, &nitems)) { + if (nitems != 4) + { + meta_verbose ("_NET_WM_ICON_GEOMETRY on %s has %d values instead of 4\n", + window->desc, nitems); + XFree (geometry); + return FALSE; + } + + if (rect) + { + rect->x = geometry[0]; + rect->y = geometry[1]; + rect->width = geometry[2]; + rect->height = geometry[3]; + } + XFree (geometry); - return FALSE; - } - - if (rect) - { - rect->x = geometry[0]; - rect->y = geometry[1]; - rect->width = geometry[2]; - rect->height = geometry[3]; + + return TRUE; } - XFree (geometry); - - return TRUE; + return FALSE; } static int diff --git a/src/xprops.c b/src/xprops.c new file mode 100644 index 000000000..f60b85e72 --- /dev/null +++ b/src/xprops.c @@ -0,0 +1,192 @@ +/* Metacity X property convenience routines */ + +/* + * Copyright (C) 2001 Havoc Pennington + * + * 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 +#include "xprops.h" +#include "errors.h" +#include "util.h" +#include + +static gboolean +check_type_and_format (MetaDisplay *display, + Window xwindow, + Atom xatom, + int expected_format, + Atom expected_type, + int format, + Atom type) +{ + char *type_name; + char *expected_name; + char *prop_name; + + if (expected_format == format && + expected_type == type) + return TRUE; + + meta_error_trap_push (display); + type_name = XGetAtomName (display->xdisplay, type); + expected_name = XGetAtomName (display->xdisplay, expected_type); + prop_name = XGetAtomName (display->xdisplay, xatom); + meta_error_trap_pop (display); + + meta_warning (_("Window 0x%lx has property %s that was expected to have type %s format %d and actually has type %s format %d\n"), + xwindow, + prop_name ? prop_name : "(bad atom)", + expected_name ? expected_name : "(bad atom)", + expected_format, + type_name ? type_name : "(bad atom)", + format); + + if (type_name) + XFree (type_name); + if (expected_name) + XFree (expected_name); + if (prop_name) + XFree (prop_name); + + return FALSE; +} + +gboolean +meta_prop_get_atom_list (MetaDisplay *display, + Window xwindow, + Atom xatom, + Atom **atoms_p, + int *n_atoms_p) +{ + Atom type; + int format; + gulong n_atoms; + gulong bytes_after; + Atom *atoms; + + *atoms_p = NULL; + *n_atoms_p = 0; + + meta_error_trap_push (display); + if (XGetWindowProperty (display->xdisplay, xwindow, xatom, + 0, G_MAXLONG, + False, XA_ATOM, &type, &format, &n_atoms, + &bytes_after, (guchar **)&atoms) != Success) + { + meta_error_trap_pop (display); + return FALSE; + } + + if (meta_error_trap_pop (display) != Success) + return FALSE; + + if (!check_type_and_format (display, xwindow, xatom, 32, XA_ATOM, + format, type)) + { + XFree (atoms); + return FALSE; + } + + *atoms_p = atoms; + *n_atoms_p = n_atoms; + + return TRUE; +} + +gboolean +meta_prop_get_cardinal_list (MetaDisplay *display, + Window xwindow, + Atom xatom, + gulong **cardinals_p, + int *n_cardinals_p) +{ + Atom type; + int format; + gulong n_cardinals; + gulong bytes_after; + gulong *cardinals; + + *cardinals_p = NULL; + *n_cardinals_p = 0; + + meta_error_trap_push (display); + if (XGetWindowProperty (display->xdisplay, xwindow, xatom, + 0, G_MAXLONG, + False, XA_CARDINAL, &type, &format, &n_cardinals, + &bytes_after, (guchar **)&cardinals) != Success) + { + meta_error_trap_pop (display); + return FALSE; + } + + if (meta_error_trap_pop (display) != Success) + return FALSE; + + if (!check_type_and_format (display, xwindow, xatom, 32, XA_CARDINAL, + format, type)) + { + XFree (cardinals); + return FALSE; + } + + *cardinals_p = cardinals; + *n_cardinals_p = n_cardinals; + + return TRUE; +} + +gboolean +meta_prop_get_motif_hints (MetaDisplay *display, + Window xwindow, + Atom xatom, + MotifWmHints **hints_p) +{ + Atom type; + int format; + gulong bytes_after; + MotifWmHints *hints; + gulong n_items; + +#define EXPECTED_ITEMS sizeof (MotifWmHints)/sizeof (gulong) + + *hints_p = NULL; + + meta_error_trap_push (display); + if (XGetWindowProperty (display->xdisplay, xwindow, xatom, + 0, EXPECTED_ITEMS, + False, AnyPropertyType, &type, &format, &n_items, + &bytes_after, (guchar **)&hints) != Success) + { + meta_error_trap_pop (display); + return FALSE; + } + + if (meta_error_trap_pop (display) != Success) + return FALSE; + + if (type == None || n_items != EXPECTED_ITEMS) + { + meta_verbose ("Motif hints had unexpected type or n_items\n"); + XFree (hints); + return FALSE; + } + + *hints_p = hints; + + return TRUE; +} diff --git a/src/xprops.h b/src/xprops.h new file mode 100644 index 000000000..28a479be5 --- /dev/null +++ b/src/xprops.h @@ -0,0 +1,89 @@ +/* Metacity X property convenience routines */ + +/* + * Copyright (C) 2001 Havoc Pennington + * + * 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_XPROPS_H +#define META_XPROPS_H + +#include "display.h" +#include + +/* Copied from Lesstif by way of GTK. Rudimentary docs can be + * found in some Motif reference guides online. + */ +typedef struct { + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long input_mode; + unsigned long status; +} MotifWmHints, MwmHints; + +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_INPUT_MODE (1L << 2) +#define MWM_HINTS_STATUS (1L << 3) + +#define MWM_FUNC_ALL (1L << 0) +#define MWM_FUNC_RESIZE (1L << 1) +#define MWM_FUNC_MOVE (1L << 2) +#define MWM_FUNC_MINIMIZE (1L << 3) +#define MWM_FUNC_MAXIMIZE (1L << 4) +#define MWM_FUNC_CLOSE (1L << 5) + +#define MWM_DECOR_ALL (1L << 0) +#define MWM_DECOR_BORDER (1L << 1) +#define MWM_DECOR_RESIZEH (1L << 2) +#define MWM_DECOR_TITLE (1L << 3) +#define MWM_DECOR_MENU (1L << 4) +#define MWM_DECOR_MINIMIZE (1L << 5) +#define MWM_DECOR_MAXIMIZE (1L << 6) + +#define MWM_INPUT_MODELESS 0 +#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 +#define MWM_INPUT_SYSTEM_MODAL 2 +#define MWM_INPUT_FULL_APPLICATION_MODAL 3 +#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL + +#define MWM_TEAROFF_WINDOW (1L<<0) + +/* These all return the memory from Xlib, so require an XFree() + * when they return TRUE. They return TRUE on success. + */ +gboolean meta_prop_get_atom_list (MetaDisplay *display, + Window xwindow, + Atom xatom, + Atom **atoms_p, + int *n_atoms_p); +gboolean meta_prop_get_motif_hints (MetaDisplay *display, + Window xwindow, + Atom xatom, + MotifWmHints **hints_p); +gboolean meta_prop_get_cardinal_list (MetaDisplay *display, + Window xwindow, + Atom xatom, + gulong **cardinals_p, + int *n_cardinals_p); + +#endif + + + +