This commit is contained in:
rhp 2001-06-08 06:39:38 +00:00
parent a6b2edc467
commit 6631763c96
4 changed files with 203 additions and 11 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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,

View File

@ -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
*/