This commit is contained in:
rhp 2001-06-23 18:30:27 +00:00
parent f9c2652e0d
commit f3d61bf7b0
6 changed files with 240 additions and 68 deletions

View File

@ -38,7 +38,8 @@ typedef enum
META_FRAME_SHADED = 1 << 7, META_FRAME_SHADED = 1 << 7,
META_FRAME_STUCK = 1 << 8, META_FRAME_STUCK = 1 << 8,
META_FRAME_MAXIMIZED = 1 << 9, META_FRAME_MAXIMIZED = 1 << 9,
META_FRAME_ALLOWS_SHADE = 1 << 10 META_FRAME_ALLOWS_SHADE = 1 << 10,
META_FRAME_ALLOWS_MOVE = 1 << 11
} MetaFrameFlags; } MetaFrameFlags;
typedef enum typedef enum

View File

@ -599,6 +599,7 @@ event_callback (XEvent *event,
{ {
meta_verbose ("Window %s withdrawn\n", meta_verbose ("Window %s withdrawn\n",
window->desc); window->desc);
window->withdrawn = TRUE;
meta_window_free (window); /* Unmanage withdrawn window */ meta_window_free (window); /* Unmanage withdrawn window */
} }
else else

View File

@ -164,8 +164,7 @@ meta_frame_get_flags (MetaFrame *frame)
{ {
MetaFrameFlags flags; MetaFrameFlags flags;
flags = flags = META_FRAME_ALLOWS_MENU;
META_FRAME_ALLOWS_MENU | META_FRAME_ALLOWS_RESIZE;
if (frame->window->has_close_func) if (frame->window->has_close_func)
flags |= META_FRAME_ALLOWS_DELETE; flags |= META_FRAME_ALLOWS_DELETE;
@ -178,6 +177,12 @@ meta_frame_get_flags (MetaFrame *frame)
if (frame->window->has_shade_func) if (frame->window->has_shade_func)
flags |= META_FRAME_ALLOWS_SHADE; flags |= META_FRAME_ALLOWS_SHADE;
if (frame->window->has_move_func)
flags |= META_FRAME_ALLOWS_MOVE;
if (frame->window->has_resize_func)
flags |= META_FRAME_ALLOWS_RESIZE;
if (frame->window->has_focus) if (frame->window->has_focus)
flags |= META_FRAME_HAS_FOCUS; flags |= META_FRAME_HAS_FOCUS;

View File

@ -598,12 +598,11 @@ meta_frames_calc_geometry (MetaFrames *frames,
} }
title_right_edge = x - props.title_border.right; title_right_edge = x - props.title_border.right;
/* Now x changes to be position from the left */ /* Now x changes to be position from the left */
x = props.left_inset; x = props.left_inset;
if ((flags & META_FRAME_ALLOWS_MENU) && if (flags & META_FRAME_ALLOWS_MENU)
x < title_right_edge)
{ {
fgeom->menu_rect.x = x + props.button_border.left; fgeom->menu_rect.x = x + props.button_border.left;
fgeom->menu_rect.y = button_y; fgeom->menu_rect.y = button_y;
@ -629,6 +628,30 @@ meta_frames_calc_geometry (MetaFrames *frames,
fgeom->close_rect.width = 0; fgeom->close_rect.width = 0;
fgeom->close_rect.height = 0; fgeom->close_rect.height = 0;
} }
/* Check for maximize overlap */
if (fgeom->max_rect.width > 0 &&
fgeom->max_rect.x < (fgeom->menu_rect.x + fgeom->menu_rect.height))
{
fgeom->max_rect.width = 0;
fgeom->max_rect.height = 0;
}
/* Check for minimize overlap */
if (fgeom->min_rect.width > 0 &&
fgeom->min_rect.x < (fgeom->menu_rect.x + fgeom->menu_rect.height))
{
fgeom->min_rect.width = 0;
fgeom->min_rect.height = 0;
}
/* Check for spacer overlap */
if (fgeom->spacer_rect.width > 0 &&
fgeom->spacer_rect.x < (fgeom->menu_rect.x + fgeom->menu_rect.height))
{
fgeom->spacer_rect.width = 0;
fgeom->spacer_rect.height = 0;
}
/* We always fill as much vertical space as possible with title rect, /* We always fill as much vertical space as possible with title rect,
* rather than centering it like the buttons and spacer * rather than centering it like the buttons and spacer
@ -1035,38 +1058,52 @@ meta_frames_button_press_event (GtkWidget *widget,
else if (control == META_FRAME_CONTROL_RESIZE_SE && else if (control == META_FRAME_CONTROL_RESIZE_SE &&
event->button == 1) event->button == 1)
{ {
int w, h; MetaFrameFlags flags;
meta_core_get_size (gdk_display,
frame->xwindow,
&w, &h);
meta_frames_begin_grab (frames, frame, flags = meta_core_get_frame_flags (gdk_display, frame->xwindow);
META_FRAME_STATUS_RESIZING_SE,
event->button, if (flags & META_FRAME_ALLOWS_RESIZE)
event->x_root, {
event->y_root, int w, h;
w, h,
event->time); meta_core_get_size (gdk_display,
frame->xwindow,
&w, &h);
meta_frames_begin_grab (frames, frame,
META_FRAME_STATUS_RESIZING_SE,
event->button,
event->x_root,
event->y_root,
w, h,
event->time);
}
} }
else if (((control == META_FRAME_CONTROL_TITLE || else if (((control == META_FRAME_CONTROL_TITLE ||
control == META_FRAME_CONTROL_NONE) && control == META_FRAME_CONTROL_NONE) &&
event->button == 1) || event->button == 1) ||
event->button == 2) event->button == 2)
{ {
int x, y; MetaFrameFlags flags;
meta_core_get_position (gdk_display,
frame->xwindow,
&x, &y);
meta_frames_begin_grab (frames, frame, flags = meta_core_get_frame_flags (gdk_display, frame->xwindow);
META_FRAME_STATUS_MOVING,
event->button, if (flags & META_FRAME_ALLOWS_MOVE)
event->x_root, {
event->y_root, int x, y;
x, y,
event->time); meta_core_get_position (gdk_display,
frame->xwindow,
&x, &y);
meta_frames_begin_grab (frames, frame,
META_FRAME_STATUS_MOVING,
event->button,
event->x_root,
event->y_root,
x, y,
event->time);
}
} }
return TRUE; return TRUE;

View File

@ -56,6 +56,7 @@ static int update_role (MetaWindow *window);
static int update_net_wm_type (MetaWindow *window); static int update_net_wm_type (MetaWindow *window);
static int update_initial_workspace (MetaWindow *window); static int update_initial_workspace (MetaWindow *window);
static void recalc_window_type (MetaWindow *window); static void recalc_window_type (MetaWindow *window);
static void recalc_window_features (MetaWindow *window);
static int set_wm_state (MetaWindow *window, static int set_wm_state (MetaWindow *window,
int state); int state);
static int set_net_wm_state (MetaWindow *window); static int set_net_wm_state (MetaWindow *window);
@ -78,6 +79,12 @@ static void meta_window_move_resize_internal (MetaWindow *window,
int w, int w,
int h); int h);
static gboolean get_cardinal (MetaDisplay *display,
Window xwindow,
Atom atom,
gulong *val);
void meta_window_unqueue_calc_showing (MetaWindow *window); void meta_window_unqueue_calc_showing (MetaWindow *window);
MetaWindow* MetaWindow*
@ -116,9 +123,20 @@ meta_window_new (MetaDisplay *display, Window xwindow,
if (must_be_viewable && attrs.map_state != IsViewable) if (must_be_viewable && attrs.map_state != IsViewable)
{ {
meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow); /* Only manage if WM_STATE is IconicState or NormalState */
meta_display_ungrab (display); gulong state;
return NULL;
if (!(get_cardinal (display, xwindow,
display->atom_wm_state,
&state) &&
(state == IconicState || state == NormalState)))
{
meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow);
meta_display_ungrab (display);
return NULL;
}
/* FIXME should honor WM_STATE probably */
} }
meta_error_trap_push (display); meta_error_trap_push (display);
@ -214,13 +232,24 @@ meta_window_new (MetaDisplay *display, Window xwindow,
window->calc_showing_queued = FALSE; window->calc_showing_queued = FALSE;
window->keys_grabbed = FALSE; window->keys_grabbed = FALSE;
window->grab_on_frame = FALSE; window->grab_on_frame = FALSE;
window->withdrawn = FALSE;
window->unmaps_pending = 0; window->unmaps_pending = 0;
window->mwm_decorated = TRUE;
window->mwm_has_close_func = TRUE;
window->mwm_has_minimize_func = TRUE;
window->mwm_has_maximize_func = TRUE;
window->mwm_has_move_func = TRUE;
window->mwm_has_resize_func = TRUE;
window->decorated = TRUE; window->decorated = TRUE;
window->has_close_func = TRUE; window->has_close_func = TRUE;
window->has_minimize_func = TRUE; window->has_minimize_func = TRUE;
window->has_maximize_func = TRUE; window->has_maximize_func = TRUE;
window->has_move_func = TRUE;
window->has_resize_func = TRUE;
window->has_shade_func = TRUE; window->has_shade_func = TRUE;
window->wm_state_modal = FALSE; window->wm_state_modal = FALSE;
@ -271,7 +300,6 @@ meta_window_new (MetaDisplay *display, Window xwindow,
set_wm_state (window, window->iconic ? IconicState : NormalState); set_wm_state (window, window->iconic ? IconicState : NormalState);
set_net_wm_state (window); set_net_wm_state (window);
/* keys grab on client window if no frame */
if (window->decorated) if (window->decorated)
meta_window_ensure_frame (window); meta_window_ensure_frame (window);
@ -306,16 +334,8 @@ meta_window_new (MetaDisplay *display, Window xwindow,
if (window->type == META_WINDOW_DESKTOP || if (window->type == META_WINDOW_DESKTOP ||
window->type == META_WINDOW_DOCK) window->type == META_WINDOW_DOCK)
{ {
/* Change around the defaults */ /* Change the default */
window->on_all_workspaces = TRUE; window->on_all_workspaces = TRUE;
window->has_close_func = FALSE;
window->has_shade_func = FALSE;
}
if (window->type != META_WINDOW_NORMAL)
{
window->has_minimize_func = FALSE;
window->has_maximize_func = FALSE;
} }
/* Put our state back where it should be, /* Put our state back where it should be,
@ -373,9 +393,10 @@ meta_window_free (MetaWindow *window)
meta_stack_remove (window->screen->stack, window); meta_stack_remove (window->screen->stack, window);
/* FIXME restore original size if window has maximized */ /* FIXME restore original size if window has maximized */
set_wm_state (window, WithdrawnState);
if (window->withdrawn)
set_wm_state (window, WithdrawnState);
if (window->frame) if (window->frame)
meta_window_destroy_frame (window); meta_window_destroy_frame (window);
@ -2152,10 +2173,12 @@ update_mwm_hints (MetaWindow *window)
gulong bytes_after; gulong bytes_after;
int result; int result;
window->decorated = TRUE; window->mwm_decorated = TRUE;
window->has_close_func = TRUE; window->mwm_has_close_func = TRUE;
window->has_minimize_func = TRUE; window->mwm_has_minimize_func = TRUE;
window->has_maximize_func = TRUE; window->mwm_has_maximize_func = TRUE;
window->mwm_has_move_func = TRUE;
window->mwm_has_resize_func = TRUE;
meta_error_trap_push (window->display); meta_error_trap_push (window->display);
XGetWindowProperty (window->display->xdisplay, window->xwindow, XGetWindowProperty (window->display->xdisplay, window->xwindow,
@ -2185,39 +2208,79 @@ update_mwm_hints (MetaWindow *window)
window->desc, hints->decorations); window->desc, hints->decorations);
if (hints->decorations == 0) if (hints->decorations == 0)
window->decorated = FALSE; window->mwm_decorated = FALSE;
} }
else else
meta_verbose ("Decorations flag unset\n"); meta_verbose ("Decorations flag unset\n");
if (hints->flags & MWM_HINTS_FUNCTIONS) if (hints->flags & MWM_HINTS_FUNCTIONS)
{ {
gboolean toggle_value;
meta_verbose ("Window %s sets MWM_HINTS_FUNCTIONS 0x%lx\n", meta_verbose ("Window %s sets MWM_HINTS_FUNCTIONS 0x%lx\n",
window->desc, hints->functions); window->desc, hints->functions);
/* If _ALL is specified, then other flags indicate what to turn off;
* if ALL is not specified, flags are what to turn on.
* at least, I think so
*/
if ((hints->flags & MWM_FUNC_ALL) == 0)
{
toggle_value = TRUE;
meta_verbose ("Window %s disables all funcs then reenables some\n",
window->desc);
window->mwm_has_close_func = FALSE;
window->mwm_has_minimize_func = FALSE;
window->mwm_has_maximize_func = FALSE;
window->mwm_has_move_func = FALSE;
window->mwm_has_resize_func = FALSE;
}
else
{
meta_verbose ("Window %s enables all funcs then disables some\n",
window->desc);
toggle_value = FALSE;
}
if ((hints->functions & MWM_FUNC_CLOSE) == 0) if ((hints->functions & MWM_FUNC_CLOSE) == 0)
{ {
meta_verbose ("Window %s disables close via MWM hints\n", meta_verbose ("Window %s toggles close via MWM hints\n",
window->desc); window->desc);
window->has_close_func = FALSE; window->mwm_has_close_func = toggle_value;
} }
if ((hints->functions & MWM_FUNC_MINIMIZE) == 0) if ((hints->functions & MWM_FUNC_MINIMIZE) == 0)
{ {
meta_verbose ("Window %s disables minimize via MWM hints\n", meta_verbose ("Window %s toggles minimize via MWM hints\n",
window->desc); window->desc);
window->has_minimize_func = FALSE; window->mwm_has_minimize_func = toggle_value;
} }
if ((hints->functions & MWM_FUNC_MAXIMIZE) == 0) if ((hints->functions & MWM_FUNC_MAXIMIZE) == 0)
{ {
meta_verbose ("Window %s disables maximize via MWM hints\n", meta_verbose ("Window %s toggles maximize via MWM hints\n",
window->desc); window->desc);
window->has_maximize_func = FALSE; window->mwm_has_maximize_func = toggle_value;
}
if ((hints->functions & MWM_FUNC_MOVE) == 0)
{
meta_verbose ("Window %s toggles move via MWM hints\n",
window->desc);
window->mwm_has_move_func = toggle_value;
}
if ((hints->functions & MWM_FUNC_RESIZE) == 0)
{
meta_verbose ("Window %s toggles resize via MWM hints\n",
window->desc);
window->mwm_has_resize_func = toggle_value;
} }
} }
else else
meta_verbose ("Functions flag unset\n"); meta_verbose ("Functions flag unset\n");
XFree (hints); XFree (hints);
recalc_window_features (window);
return Success; return Success;
} }
@ -2426,7 +2489,8 @@ update_transient_for (MetaWindow *window)
static gboolean static gboolean
get_cardinal (MetaWindow *window, get_cardinal (MetaDisplay *display,
Window xwindow,
Atom atom, Atom atom,
gulong *val) gulong *val)
{ {
@ -2437,15 +2501,15 @@ get_cardinal (MetaWindow *window,
gulong *num; gulong *num;
int err; int err;
meta_error_trap_push (window->display); meta_error_trap_push (display);
type = None; type = None;
XGetWindowProperty (window->display->xdisplay, XGetWindowProperty (display->xdisplay,
window->xwindow, xwindow,
atom, atom,
0, G_MAXLONG, 0, G_MAXLONG,
False, XA_CARDINAL, &type, &format, &nitems, False, XA_CARDINAL, &type, &format, &nitems,
&bytes_after, (guchar **)&num); &bytes_after, (guchar **)&num);
err = meta_error_trap_pop (window->display); err = meta_error_trap_pop (display);
if (err != Success) if (err != Success)
return FALSE; return FALSE;
@ -2497,7 +2561,9 @@ update_net_wm_type (MetaWindow *window)
/* Fall back to WIN_LAYER */ /* Fall back to WIN_LAYER */
gulong layer = WIN_LAYER_NORMAL; gulong layer = WIN_LAYER_NORMAL;
if (get_cardinal (window, window->display->atom_win_layer, if (get_cardinal (window->display,
window->xwindow,
window->display->atom_win_layer,
&layer)) &layer))
{ {
meta_verbose ("%s falling back to _WIN_LAYER hint, layer %ld\n", meta_verbose ("%s falling back to _WIN_LAYER hint, layer %ld\n",
@ -2576,10 +2642,14 @@ update_initial_workspace (MetaWindow *window)
* is just to be nice when restarting from old Sawfish basically, * is just to be nice when restarting from old Sawfish basically,
* should nuke it eventually * should nuke it eventually
*/ */
if (get_cardinal (window, window->display->atom_net_wm_desktop, if (get_cardinal (window->display,
window->xwindow,
window->display->atom_net_wm_desktop,
&val)) &val))
window->initial_workspace = val; window->initial_workspace = val;
else if (get_cardinal (window, window->display->atom_win_workspace, else if (get_cardinal (window->display,
window->xwindow,
window->display->atom_win_workspace,
&val)) &val))
window->initial_workspace = val; window->initial_workspace = val;
@ -2625,13 +2695,56 @@ recalc_window_type (MetaWindow *window)
if (old_type != window->type) if (old_type != window->type)
{ {
recalc_window_features (window);
set_net_wm_state (window); set_net_wm_state (window);
/* Update frame */
if (window->decorated)
meta_window_ensure_frame (window);
else
meta_window_destroy_frame (window);
/* update stacking constraints */ /* update stacking constraints */
meta_stack_update_layer (window->screen->stack, window); meta_stack_update_layer (window->screen->stack, window);
} }
} }
static void
recalc_window_features (MetaWindow *window)
{
/* Use MWM hints initially */
window->decorated = window->mwm_decorated;
window->has_close_func = window->mwm_has_close_func;
window->has_minimize_func = window->mwm_has_minimize_func;
window->has_maximize_func = window->mwm_has_maximize_func;
window->has_move_func = window->mwm_has_move_func;
window->has_resize_func = window->mwm_has_resize_func;
window->has_shade_func = TRUE;
/* Semantic category overrides the MWM hints */
if (window->type == META_WINDOW_DESKTOP ||
window->type == META_WINDOW_DOCK)
{
window->has_close_func = FALSE;
window->has_shade_func = FALSE;
window->has_move_func = FALSE;
window->has_resize_func = FALSE;
}
if (window->type != META_WINDOW_NORMAL)
{
window->has_minimize_func = FALSE;
window->has_maximize_func = FALSE;
}
/* FIXME perhaps should ensure if we don't have a shade func,
* we aren't shaded, etc.
*/
}
static void static void
constrain_size (MetaWindow *window, constrain_size (MetaWindow *window,
MetaFrameGeometry *fgeom, MetaFrameGeometry *fgeom,
@ -2792,7 +2905,7 @@ constrain_position (MetaWindow *window,
if (parent) if (parent)
{ {
int w; int w;
meta_window_get_position (parent, &x, &y); meta_window_get_position (parent, &x, &y);
w = parent->rect.width; w = parent->rect.width;

View File

@ -104,12 +104,22 @@ struct _MetaWindow
/* Globally active / No input */ /* Globally active / No input */
guint input : 1; guint input : 1;
/* Features of window */ /* MWM hints about features of window */
guint mwm_decorated : 1;
guint mwm_has_close_func : 1;
guint mwm_has_minimize_func : 1;
guint mwm_has_maximize_func : 1;
guint mwm_has_move_func : 1;
guint mwm_has_resize_func : 1;
/* Computed features of window */
guint decorated : 1; guint decorated : 1;
guint has_close_func : 1; guint has_close_func : 1;
guint has_minimize_func : 1; guint has_minimize_func : 1;
guint has_maximize_func : 1; guint has_maximize_func : 1;
guint has_shade_func : 1; guint has_shade_func : 1;
guint has_move_func : 1;
guint has_resize_func : 1;
/* Weird "_NET_WM_STATE_MODAL" flag */ /* Weird "_NET_WM_STATE_MODAL" flag */
guint wm_state_modal : 1; guint wm_state_modal : 1;
@ -144,6 +154,11 @@ struct _MetaWindow
/* Used by keybindings.c */ /* Used by keybindings.c */
guint keys_grabbed : 1; guint keys_grabbed : 1;
guint grab_on_frame : 1; guint grab_on_frame : 1;
/* Set if the reason for unmanaging the window is that
* it was withdrawn
*/
guint withdrawn : 1;
/* Number of UnmapNotify that are caused by us, if /* Number of UnmapNotify that are caused by us, if
* we get UnmapNotify with none pending then the client * we get UnmapNotify with none pending then the client