summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrhp <rhp>2001-06-23 18:30:27 +0000
committerrhp <rhp>2001-06-23 18:30:27 +0000
commitf3d61bf7b024b6926fb8bba889c2b6a778d9b0ff (patch)
treee2795d11bee2974dd1c8cf4a0c92dc1a0c0b4d31
parentf9c2652e0d7c0edd76459366159701134a0444b5 (diff)
downloadmutter-f3d61bf7b024b6926fb8bba889c2b6a778d9b0ff.tar.gz
...
-rw-r--r--src/common.h3
-rw-r--r--src/display.c1
-rw-r--r--src/frame.c9
-rw-r--r--src/frames.c91
-rw-r--r--src/window.c187
-rw-r--r--src/window.h17
6 files changed, 240 insertions, 68 deletions
diff --git a/src/common.h b/src/common.h
index 5f5411b1f..aacb8f402 100644
--- a/src/common.h
+++ b/src/common.h
@@ -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
diff --git a/src/display.c b/src/display.c
index 76408122b..6ff12f0de 100644
--- a/src/display.c
+++ b/src/display.c
@@ -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
diff --git a/src/frame.c b/src/frame.c
index 758be83f2..533a8f082 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -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;
diff --git a/src/frames.c b/src/frames.c
index 07ddfab6d..0c82a501a 100644
--- a/src/frames.c
+++ b/src/frames.c
@@ -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;
diff --git a/src/window.c b/src/window.c
index 46daf7b25..a13ccefc3 100644
--- a/src/window.c
+++ b/src/window.c
@@ -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->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->has_maximize_func = FALSE;
+ 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,14 +2695,57 @@ 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,
int width, int height,
@@ -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;
diff --git a/src/window.h b/src/window.h
index fa103736b..218fd5cb4 100644
--- a/src/window.h
+++ b/src/window.h
@@ -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