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_STUCK = 1 << 8,
META_FRAME_MAXIMIZED = 1 << 9,
META_FRAME_ALLOWS_SHADE = 1 << 10
META_FRAME_ALLOWS_SHADE = 1 << 10,
META_FRAME_ALLOWS_MOVE = 1 << 11
} MetaFrameFlags;
typedef enum

View File

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

View File

@ -164,8 +164,7 @@ meta_frame_get_flags (MetaFrame *frame)
{
MetaFrameFlags flags;
flags =
META_FRAME_ALLOWS_MENU | META_FRAME_ALLOWS_RESIZE;
flags = META_FRAME_ALLOWS_MENU;
if (frame->window->has_close_func)
flags |= META_FRAME_ALLOWS_DELETE;
@ -178,6 +177,12 @@ meta_frame_get_flags (MetaFrame *frame)
if (frame->window->has_shade_func)
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)
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;
/* Now x changes to be position from the left */
x = props.left_inset;
if ((flags & META_FRAME_ALLOWS_MENU) &&
x < title_right_edge)
if (flags & META_FRAME_ALLOWS_MENU)
{
fgeom->menu_rect.x = x + props.button_border.left;
fgeom->menu_rect.y = button_y;
@ -629,6 +628,30 @@ meta_frames_calc_geometry (MetaFrames *frames,
fgeom->close_rect.width = 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,
* 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 &&
event->button == 1)
{
int w, h;
meta_core_get_size (gdk_display,
frame->xwindow,
&w, &h);
MetaFrameFlags flags;
meta_frames_begin_grab (frames, frame,
META_FRAME_STATUS_RESIZING_SE,
event->button,
event->x_root,
event->y_root,
w, h,
event->time);
flags = meta_core_get_frame_flags (gdk_display, frame->xwindow);
if (flags & META_FRAME_ALLOWS_RESIZE)
{
int w, h;
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 ||
control == META_FRAME_CONTROL_NONE) &&
event->button == 1) ||
event->button == 2)
{
int x, y;
meta_core_get_position (gdk_display,
frame->xwindow,
&x, &y);
MetaFrameFlags flags;
meta_frames_begin_grab (frames, frame,
META_FRAME_STATUS_MOVING,
event->button,
event->x_root,
event->y_root,
x, y,
event->time);
flags = meta_core_get_frame_flags (gdk_display, frame->xwindow);
if (flags & META_FRAME_ALLOWS_MOVE)
{
int x, y;
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;

View File

@ -56,6 +56,7 @@ static int update_role (MetaWindow *window);
static int update_net_wm_type (MetaWindow *window);
static int update_initial_workspace (MetaWindow *window);
static void recalc_window_type (MetaWindow *window);
static void recalc_window_features (MetaWindow *window);
static int set_wm_state (MetaWindow *window,
int state);
static int set_net_wm_state (MetaWindow *window);
@ -78,6 +79,12 @@ static void meta_window_move_resize_internal (MetaWindow *window,
int w,
int h);
static gboolean get_cardinal (MetaDisplay *display,
Window xwindow,
Atom atom,
gulong *val);
void meta_window_unqueue_calc_showing (MetaWindow *window);
MetaWindow*
@ -116,9 +123,20 @@ meta_window_new (MetaDisplay *display, Window xwindow,
if (must_be_viewable && attrs.map_state != IsViewable)
{
meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow);
meta_display_ungrab (display);
return NULL;
/* Only manage if WM_STATE is IconicState or NormalState */
gulong state;
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);
@ -214,13 +232,24 @@ meta_window_new (MetaDisplay *display, Window xwindow,
window->calc_showing_queued = FALSE;
window->keys_grabbed = FALSE;
window->grab_on_frame = FALSE;
window->withdrawn = FALSE;
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->has_close_func = TRUE;
window->has_minimize_func = TRUE;
window->has_maximize_func = TRUE;
window->has_move_func = TRUE;
window->has_resize_func = TRUE;
window->has_shade_func = TRUE;
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_net_wm_state (window);
/* keys grab on client window if no frame */
if (window->decorated)
meta_window_ensure_frame (window);
@ -306,16 +334,8 @@ meta_window_new (MetaDisplay *display, Window xwindow,
if (window->type == META_WINDOW_DESKTOP ||
window->type == META_WINDOW_DOCK)
{
/* Change around the defaults */
/* Change the default */
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,
@ -373,9 +393,10 @@ meta_window_free (MetaWindow *window)
meta_stack_remove (window->screen->stack, window);
/* FIXME restore original size if window has maximized */
set_wm_state (window, WithdrawnState);
if (window->withdrawn)
set_wm_state (window, WithdrawnState);
if (window->frame)
meta_window_destroy_frame (window);
@ -2152,10 +2173,12 @@ update_mwm_hints (MetaWindow *window)
gulong bytes_after;
int result;
window->decorated = TRUE;
window->has_close_func = TRUE;
window->has_minimize_func = TRUE;
window->has_maximize_func = TRUE;
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;
meta_error_trap_push (window->display);
XGetWindowProperty (window->display->xdisplay, window->xwindow,
@ -2185,39 +2208,79 @@ update_mwm_hints (MetaWindow *window)
window->desc, hints->decorations);
if (hints->decorations == 0)
window->decorated = FALSE;
window->mwm_decorated = FALSE;
}
else
meta_verbose ("Decorations flag unset\n");
if (hints->flags & MWM_HINTS_FUNCTIONS)
{
gboolean toggle_value;
meta_verbose ("Window %s sets MWM_HINTS_FUNCTIONS 0x%lx\n",
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)
{
meta_verbose ("Window %s disables close via MWM hints\n",
meta_verbose ("Window %s toggles close via MWM hints\n",
window->desc);
window->has_close_func = FALSE;
window->mwm_has_close_func = toggle_value;
}
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->has_minimize_func = FALSE;
window->mwm_has_minimize_func = toggle_value;
}
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->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
meta_verbose ("Functions flag unset\n");
XFree (hints);
recalc_window_features (window);
return Success;
}
@ -2426,7 +2489,8 @@ update_transient_for (MetaWindow *window)
static gboolean
get_cardinal (MetaWindow *window,
get_cardinal (MetaDisplay *display,
Window xwindow,
Atom atom,
gulong *val)
{
@ -2437,15 +2501,15 @@ get_cardinal (MetaWindow *window,
gulong *num;
int err;
meta_error_trap_push (window->display);
meta_error_trap_push (display);
type = None;
XGetWindowProperty (window->display->xdisplay,
window->xwindow,
XGetWindowProperty (display->xdisplay,
xwindow,
atom,
0, G_MAXLONG,
False, XA_CARDINAL, &type, &format, &nitems,
&bytes_after, (guchar **)&num);
err = meta_error_trap_pop (window->display);
err = meta_error_trap_pop (display);
if (err != Success)
return FALSE;
@ -2497,7 +2561,9 @@ update_net_wm_type (MetaWindow *window)
/* Fall back to WIN_LAYER */
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))
{
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,
* 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))
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))
window->initial_workspace = val;
@ -2625,13 +2695,56 @@ recalc_window_type (MetaWindow *window)
if (old_type != window->type)
{
recalc_window_features (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 */
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
constrain_size (MetaWindow *window,
MetaFrameGeometry *fgeom,
@ -2792,7 +2905,7 @@ constrain_position (MetaWindow *window,
if (parent)
{
int w;
int w;
meta_window_get_position (parent, &x, &y);
w = parent->rect.width;

View File

@ -104,12 +104,22 @@ struct _MetaWindow
/* Globally active / No input */
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 has_close_func : 1;
guint has_minimize_func : 1;
guint has_maximize_func : 1;
guint has_shade_func : 1;
guint has_move_func : 1;
guint has_resize_func : 1;
/* Weird "_NET_WM_STATE_MODAL" flag */
guint wm_state_modal : 1;
@ -144,6 +154,11 @@ struct _MetaWindow
/* Used by keybindings.c */
guint keys_grabbed : 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
* we get UnmapNotify with none pending then the client