From 6631763c96c6ccae0590d2ff098e1d66423b4317 Mon Sep 17 00:00:00 2001 From: rhp Date: Fri, 8 Jun 2001 06:39:38 +0000 Subject: [PATCH] ... --- src/display.c | 16 ++++- src/display.h | 5 ++ src/window.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++--- src/window.h | 8 ++- 4 files changed, 203 insertions(+), 11 deletions(-) diff --git a/src/display.c b/src/display.c index 8a38fdb16..7858951b7 100644 --- a/src/display.c +++ b/src/display.c @@ -79,7 +79,12 @@ meta_display_open (const char *name) "WM_TAKE_FOCUS", "WM_DELETE_WINDOW", "WM_STATE", - "_NET_CLOSE_WINDOW" + "_NET_CLOSE_WINDOW", + "_NET_WM_STATE", + "MOTIF_WM_HINTS", + "_NET_WM_STATE_SHADED", + "_NET_WM_STATE_MAXIMIZED_HORZ", + "_NET_WM_STATE_MAXIMIZED_VERT" }; Atom atoms[G_N_ELEMENTS(atom_names)]; @@ -157,7 +162,12 @@ meta_display_open (const char *name) display->atom_wm_delete_window = atoms[3]; display->atom_wm_state = atoms[4]; display->atom_net_close_window = atoms[5]; - + display->atom_net_wm_state = atoms[6]; + display->atom_motif_wm_hints = atoms[7]; + display->atom_net_wm_state_shaded = atoms[8]; + display->atom_net_wm_state_maximized_horz = atoms[9]; + display->atom_net_wm_state_maximized_vert = atoms[10]; + display->double_click_time = 250; display->last_button_time = 0; display->last_button_xwindow = None; @@ -499,6 +509,8 @@ event_queue_callback (MetaEventQueue *queue, xwc.height = event->xconfigurerequest.height; xwc.border_width = event->xconfigurerequest.border_width; + meta_verbose ("Configuring withdrawn window to %d,%d %dx%d border %d\n", + xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width); XConfigureWindow (display->xdisplay, event->xconfigurerequest.window, xwcm, &xwc); } diff --git a/src/display.h b/src/display.h index bdb03be66..45be6ae8e 100644 --- a/src/display.h +++ b/src/display.h @@ -45,6 +45,11 @@ struct _MetaDisplay Atom atom_wm_delete_window; Atom atom_wm_state; Atom atom_net_close_window; + Atom atom_net_wm_state; + Atom atom_motif_wm_hints; + Atom atom_net_wm_state_shaded; + Atom atom_net_wm_state_maximized_horz; + Atom atom_net_wm_state_maximized_vert; /* This is the actual window from focus events, * not the one we last set diff --git a/src/window.c b/src/window.c index 8e169f3b2..a06730499 100644 --- a/src/window.c +++ b/src/window.c @@ -36,6 +36,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 int set_wm_state (MetaWindow *window, int state); static void send_configure_notify (MetaWindow *window); @@ -148,6 +150,11 @@ meta_window_new (MetaDisplay *display, Window xwindow) window->minimized = FALSE; window->iconic = FALSE; window->mapped = FALSE; + + window->decorated = TRUE; + window->has_close_func = TRUE; + window->has_minimize_func = TRUE; + window->has_maximize_func = TRUE; meta_display_register_x_window (display, &window->xwindow, window); @@ -155,7 +162,9 @@ meta_window_new (MetaDisplay *display, Window xwindow) update_title (window); update_protocols (window); update_wm_hints (window); - + update_net_wm_state (window); + update_mwm_hints (window); + if (window->initially_iconic) { /* WM_HINTS said minimized */ @@ -171,8 +180,9 @@ meta_window_new (MetaDisplay *display, Window xwindow) * change it again. */ set_wm_state (window, window->iconic ? IconicState : NormalState); - - meta_window_ensure_frame (window); + + if (window->decorated) + meta_window_ensure_frame (window); meta_workspace_add_window (window->screen->active_workspace, window); @@ -293,8 +303,10 @@ meta_window_show (MetaWindow *window) if (window->shaded) { window->mapped = FALSE; + meta_error_trap_push (window->display); XUnmapWindow (window->display->xdisplay, window->xwindow); - + meta_error_trap_pop (window->display); + if (!window->iconic) { window->iconic = TRUE; @@ -304,8 +316,10 @@ meta_window_show (MetaWindow *window) else { window->mapped = TRUE; + meta_error_trap_push (window->display); XMapWindow (window->display->xdisplay, window->xwindow); - + meta_error_trap_pop (window->display); + if (window->iconic) { window->iconic = FALSE; @@ -715,6 +729,18 @@ process_property_notify (MetaWindow *window, if (window->frame) meta_frame_queue_recalc (window->frame); } + else if (event->atom == window->display->atom_motif_wm_hints) + { + update_mwm_hints (window); + + if (window->decorated) + meta_window_ensure_frame (window); + else + meta_window_destroy_frame (window); + + if (window->frame) + meta_frame_queue_recalc (window->frame); + } return TRUE; } @@ -857,7 +883,7 @@ static int update_size_hints (MetaWindow *window) { int x, y, w, h; - + /* Save the last ConfigureRequest, which we put here. * Values here set in the hints are supposed to * be ignored. @@ -873,7 +899,7 @@ update_size_hints (MetaWindow *window) XGetNormalHints (window->display->xdisplay, window->xwindow, &window->size_hints); - + /* Put it back. */ window->size_hints.x = x; window->size_hints.y = y; @@ -991,7 +1017,7 @@ update_size_hints (MetaWindow *window) window->size_hints.win_gravity = NorthWestGravity; window->size_hints.flags |= PWinGravity; } - + return meta_error_trap_pop (window->display); } @@ -1143,6 +1169,149 @@ update_wm_hints (MetaWindow *window) return meta_error_trap_pop (window->display); } +static int +update_net_wm_state (MetaWindow *window) +{ + /* We know this is only on initial window creation, + * clients don't change the property. + */ + Atom type; + gint format; + gulong n_atoms; + gulong bytes_after; + Atom *atoms; + int result; + int i; + + window->shaded = FALSE; + window->maximized = 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) + return result; + + if (type != XA_ATOM) + 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; + + ++i; + } + + XFree (atoms); + + 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 +update_mwm_hints (MetaWindow *window) +{ + MotifWmHints *hints; + Atom type; + gint format; + gulong nitems; + gulong bytes_after; + int result; + + window->decorated = TRUE; + window->has_close_func = TRUE; + window->has_minimize_func = TRUE; + window->has_maximize_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) + return result; + + if (type == None) + return -1; /* whatever */ + + /* We support MWM hints deemed non-stupid */ + + if (hints->flags & MWM_HINTS_DECORATIONS) + { + if (hints->decorations == 0) + window->decorated = FALSE; + } + + if (hints->flags & MWM_HINTS_FUNCTIONS) + { + if ((hints->functions & MWM_FUNC_CLOSE) == 0) + window->has_close_func = FALSE; + if ((hints->functions & MWM_FUNC_MINIMIZE) == 0) + window->has_minimize_func = FALSE; + if ((hints->functions & MWM_FUNC_MAXIMIZE) == 0) + window->has_maximize_func = FALSE; + } + + XFree (hints); + + return Success; +} + static void constrain_size (MetaWindow *window, int width, int height, diff --git a/src/window.h b/src/window.h index 84e7f3b44..bd3bf2701 100644 --- a/src/window.h +++ b/src/window.h @@ -69,7 +69,13 @@ struct _MetaWindow guint delete_window : 1; /* Globally active / No input */ guint input : 1; - + + /* MWM hints */ + guint decorated : 1; + guint has_close_func : 1; + guint has_minimize_func : 1; + guint has_maximize_func : 1; + /* this flag tracks receipt of focus_in focus_out and * determines whether we draw the focus */