mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
cheesy client with static bit gravity, used to test the below change.
2002-01-19 Havoc Pennington <hp@pobox.com> * src/wm-tester/test-resizing.c: cheesy client with static bit gravity, used to test the below change. * src/window.c (meta_window_move_resize_internal): implement Owen's proposal for window resizing. http://mail.gnome.org/archives/wm-spec-list/1999-November/msg00088.html Currently you have to do METACITY_USE_STATIC_GRAVITY=1 in order to use it, because some GDK bug is screwing up exposes on my frames when it's enabled. * src/display.c (meta_display_create_x_cursor): fix glyph for NE/NW cursors * src/frames.c (get_control): add ability to resize from top * src/frame.c (meta_frame_get_flags): can't resize shaded windows (meta_frame_sync_to_window): add gravity arg * src/common.h (MetaWindowType): move here from window.h so it can be used in themes stuff. (MetaFrameFlags): remove META_FRAME_TRANSIENT since it overlaps with window type and was unused.
This commit is contained in:
parent
19d2e8c7e1
commit
5fdb8463de
26
ChangeLog
26
ChangeLog
@ -1,3 +1,29 @@
|
||||
2002-01-19 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* src/wm-tester/test-resizing.c: cheesy client with static
|
||||
bit gravity, used to test the below change.
|
||||
|
||||
* src/window.c (meta_window_move_resize_internal): implement
|
||||
Owen's proposal for window resizing.
|
||||
http://mail.gnome.org/archives/wm-spec-list/1999-November/msg00088.html
|
||||
|
||||
Currently you have to do METACITY_USE_STATIC_GRAVITY=1 in order to
|
||||
use it, because some GDK bug is screwing up exposes on my frames
|
||||
when it's enabled.
|
||||
|
||||
* src/display.c (meta_display_create_x_cursor): fix glyph for
|
||||
NE/NW cursors
|
||||
|
||||
* src/frames.c (get_control): add ability to resize from top
|
||||
|
||||
* src/frame.c (meta_frame_get_flags): can't resize shaded windows
|
||||
(meta_frame_sync_to_window): add gravity arg
|
||||
|
||||
* src/common.h (MetaWindowType): move here from window.h so
|
||||
it can be used in themes stuff.
|
||||
(MetaFrameFlags): remove META_FRAME_TRANSIENT since it
|
||||
overlaps with window type and was unused.
|
||||
|
||||
2002-01-18 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* src/window.c (constrain_position): give priority to keeping NW
|
||||
|
26
src/common.h
26
src/common.h
@ -34,13 +34,12 @@ typedef enum
|
||||
META_FRAME_ALLOWS_MAXIMIZE = 1 << 3,
|
||||
META_FRAME_ALLOWS_VERTICAL_RESIZE = 1 << 4,
|
||||
META_FRAME_ALLOWS_HORIZONTAL_RESIZE = 1 << 5,
|
||||
META_FRAME_TRANSIENT = 1 << 6,
|
||||
META_FRAME_HAS_FOCUS = 1 << 7,
|
||||
META_FRAME_SHADED = 1 << 8,
|
||||
META_FRAME_STUCK = 1 << 9,
|
||||
META_FRAME_MAXIMIZED = 1 << 10,
|
||||
META_FRAME_ALLOWS_SHADE = 1 << 11,
|
||||
META_FRAME_ALLOWS_MOVE = 1 << 12
|
||||
META_FRAME_HAS_FOCUS = 1 << 6,
|
||||
META_FRAME_SHADED = 1 << 7,
|
||||
META_FRAME_STUCK = 1 << 8,
|
||||
META_FRAME_MAXIMIZED = 1 << 9,
|
||||
META_FRAME_ALLOWS_SHADE = 1 << 10,
|
||||
META_FRAME_ALLOWS_MOVE = 1 << 11
|
||||
} MetaFrameFlags;
|
||||
|
||||
typedef enum
|
||||
@ -130,6 +129,19 @@ typedef enum
|
||||
META_FOCUS_MODE_MOUSE
|
||||
} MetaFocusMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_WINDOW_NORMAL,
|
||||
META_WINDOW_DESKTOP,
|
||||
META_WINDOW_DOCK,
|
||||
META_WINDOW_DIALOG,
|
||||
META_WINDOW_MODAL_DIALOG,
|
||||
META_WINDOW_TOOLBAR,
|
||||
META_WINDOW_MENU,
|
||||
META_WINDOW_TYPE_LAST
|
||||
} MetaWindowType;
|
||||
|
||||
|
||||
/* should investigate changing these to whatever most apps use */
|
||||
#define META_ICON_WIDTH 32
|
||||
#define META_ICON_HEIGHT 32
|
||||
|
@ -179,6 +179,9 @@ meta_display_open (const char *name)
|
||||
display->prev_focus_window = NULL;
|
||||
|
||||
display->showing_desktop = FALSE;
|
||||
|
||||
/* FIXME copy the checks from GDK probably */
|
||||
display->static_gravity_works = g_getenv ("METACITY_USE_STATIC_GRAVITY") != NULL;
|
||||
|
||||
/* we have to go ahead and do this so error handlers work */
|
||||
all_displays = g_slist_prepend (all_displays, display);
|
||||
@ -1638,10 +1641,10 @@ meta_display_create_x_cursor (MetaDisplay *display,
|
||||
glyph = XC_bottom_left_corner;
|
||||
break;
|
||||
case META_CURSOR_NE_RESIZE:
|
||||
glyph = XC_top_left_corner;
|
||||
glyph = XC_top_right_corner;
|
||||
break;
|
||||
case META_CURSOR_NW_RESIZE:
|
||||
glyph = XC_top_right_corner;
|
||||
glyph = XC_top_left_corner;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -118,6 +118,7 @@ struct _MetaDisplay
|
||||
GList *workspaces;
|
||||
|
||||
guint showing_desktop : 1;
|
||||
guint static_gravity_works : 1;
|
||||
|
||||
/*< private-ish >*/
|
||||
MetaEventQueue *events;
|
||||
|
@ -210,7 +210,8 @@ meta_frame_get_flags (MetaFrame *frame)
|
||||
flags |= META_FRAME_ALLOWS_MOVE;
|
||||
|
||||
if (frame->window->has_resize_func &&
|
||||
!frame->window->maximized)
|
||||
!frame->window->maximized &&
|
||||
!frame->window->shaded)
|
||||
{
|
||||
if (frame->window->size_hints.min_width <
|
||||
frame->window->size_hints.max_width)
|
||||
@ -256,7 +257,8 @@ meta_frame_calc_geometry (MetaFrame *frame,
|
||||
}
|
||||
|
||||
static void
|
||||
set_background_none (MetaFrame *frame)
|
||||
set_background_none (MetaFrame *frame,
|
||||
int resize_gravity)
|
||||
{
|
||||
XSetWindowAttributes attrs;
|
||||
|
||||
@ -269,6 +271,7 @@ set_background_none (MetaFrame *frame)
|
||||
|
||||
void
|
||||
meta_frame_sync_to_window (MetaFrame *frame,
|
||||
int resize_gravity,
|
||||
gboolean need_move,
|
||||
gboolean need_resize)
|
||||
{
|
||||
@ -283,7 +286,7 @@ meta_frame_sync_to_window (MetaFrame *frame,
|
||||
|
||||
/* set bg to none to avoid flicker */
|
||||
if (need_resize)
|
||||
set_background_none (frame);
|
||||
set_background_none (frame, resize_gravity);
|
||||
|
||||
if (need_move && need_resize)
|
||||
XMoveResizeWindow (frame->window->display->xdisplay,
|
||||
|
@ -67,6 +67,7 @@ MetaFrameFlags meta_frame_get_flags (MetaFrame *frame);
|
||||
void meta_frame_calc_geometry (MetaFrame *frame,
|
||||
MetaFrameGeometry *geomp);
|
||||
void meta_frame_sync_to_window (MetaFrame *frame,
|
||||
int gravity,
|
||||
gboolean need_move,
|
||||
gboolean need_resize);
|
||||
|
||||
|
29
src/frames.c
29
src/frames.c
@ -2042,8 +2042,28 @@ get_control (MetaFrames *frames,
|
||||
|
||||
if (has_vert || has_horiz)
|
||||
{
|
||||
if (y >= (fgeom.height - fgeom.bottom_height - RESIZE_EXTENDS) &&
|
||||
x >= (fgeom.width - fgeom.right_width - RESIZE_EXTENDS))
|
||||
if (y < fgeom.top_height && x < RESIZE_EXTENDS)
|
||||
{
|
||||
if (has_vert && has_horiz)
|
||||
return META_FRAME_CONTROL_RESIZE_NW;
|
||||
else if (has_vert)
|
||||
return META_FRAME_CONTROL_RESIZE_N;
|
||||
else
|
||||
return META_FRAME_CONTROL_RESIZE_W;
|
||||
|
||||
}
|
||||
else if (y < fgeom.top_height && x >= (fgeom.width - RESIZE_EXTENDS))
|
||||
{
|
||||
if (has_vert && has_horiz)
|
||||
return META_FRAME_CONTROL_RESIZE_NE;
|
||||
else if (has_vert)
|
||||
return META_FRAME_CONTROL_RESIZE_N;
|
||||
else
|
||||
return META_FRAME_CONTROL_RESIZE_E;
|
||||
|
||||
}
|
||||
else if (y >= (fgeom.height - fgeom.bottom_height - RESIZE_EXTENDS) &&
|
||||
x >= (fgeom.width - fgeom.right_width - RESIZE_EXTENDS))
|
||||
{
|
||||
if (has_vert && has_horiz)
|
||||
return META_FRAME_CONTROL_RESIZE_SE;
|
||||
@ -2062,6 +2082,11 @@ get_control (MetaFrames *frames,
|
||||
else
|
||||
return META_FRAME_CONTROL_RESIZE_W;
|
||||
}
|
||||
else if (y < fgeom.top_height)
|
||||
{
|
||||
if (has_vert)
|
||||
return META_FRAME_CONTROL_RESIZE_N;
|
||||
}
|
||||
else if (y >= (fgeom.height - fgeom.bottom_height - RESIZE_EXTENDS))
|
||||
{
|
||||
if (has_vert)
|
||||
|
105
src/theme.c
105
src/theme.c
@ -666,3 +666,108 @@ meta_texture_spec_draw (const MetaTextureSpec *spec,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MetaFrameStyle*
|
||||
meta_frame_style_new (void)
|
||||
{
|
||||
MetaFrameStyle *style;
|
||||
|
||||
style = g_new0 (MetaFrameStyle, 1);
|
||||
|
||||
style->refcount = 1;
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_style_ref (MetaFrameStyle *style)
|
||||
{
|
||||
g_return_if_fail (style != NULL);
|
||||
|
||||
style->refcount += 1;
|
||||
}
|
||||
|
||||
static void
|
||||
free_button_textures (MetaTextureSpec *textures[META_BUTTON_TYPE_LAST][META_BUTTON_STATE_LAST])
|
||||
{
|
||||
int i, j;
|
||||
|
||||
i = 0;
|
||||
while (i < META_BUTTON_TYPE_LAST)
|
||||
{
|
||||
j = 0;
|
||||
while (j < META_BUTTON_STATE_LAST)
|
||||
{
|
||||
if (textures[i][j])
|
||||
meta_texture_spec_free (textures[i][j]);
|
||||
|
||||
++j;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_style_unref (MetaFrameStyle *style)
|
||||
{
|
||||
g_return_if_fail (style != NULL);
|
||||
g_return_if_fail (style->refcount > 0);
|
||||
|
||||
style->refcount -= 1;
|
||||
|
||||
if (style->refcount == 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
free_button_textures (style->button_icons);
|
||||
free_button_textures (style->button_backgrounds);
|
||||
|
||||
i = 0;
|
||||
while (i < META_FRAME_PIECE_LAST)
|
||||
{
|
||||
if (style->pieces[i])
|
||||
meta_texture_spec_free (style->pieces[i]);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
if (style->layout)
|
||||
meta_frame_layout_free (style->layout);
|
||||
|
||||
g_free (style);
|
||||
}
|
||||
}
|
||||
|
||||
MetaFrameStyleSet*
|
||||
meta_frame_style_set_new (void)
|
||||
{
|
||||
MetaFrameStyleSet *style_set;
|
||||
|
||||
style_set = g_new0 (MetaFrameStyleSet, 1);
|
||||
|
||||
return style_set;
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_style_set_free (MetaFrameStyleSet *style_set)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
i = 0;
|
||||
while (i < META_WINDOW_TYPE_LAST)
|
||||
{
|
||||
j = 0;
|
||||
while (j < META_WINDOW_STATE_LAST)
|
||||
{
|
||||
if (style_set->styles[i][j])
|
||||
meta_frame_style_unref (style_set->styles[i][j]);
|
||||
|
||||
++j;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
g_free (style_set);
|
||||
}
|
||||
|
64
src/theme.h
64
src/theme.h
@ -133,6 +133,14 @@ typedef enum
|
||||
META_TEXTURE_IMAGE
|
||||
} MetaTextureType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_TEXTURE_DRAW_UNSCALED,
|
||||
META_TEXTURE_DRAW_SCALED_VERTICALLY,
|
||||
META_TEXTURE_DRAW_SCALED_HORIZONTALLY,
|
||||
META_TEXTURE_DRAW_SCALED_BOTH
|
||||
} MetaTextureDrawMode;
|
||||
|
||||
struct _MetaTextureSpec
|
||||
{
|
||||
MetaTextureType type;
|
||||
@ -243,22 +251,60 @@ typedef enum
|
||||
|
||||
struct _MetaFrameStyle
|
||||
{
|
||||
int refcount;
|
||||
MetaTextureSpec *button_icons[META_BUTTON_TYPE_LAST][META_BUTTON_STATE_LAST];
|
||||
MetaTextureSpec *button_backgrounds[META_BUTTON_TYPE_LAST][META_BUTTON_STATE_LAST];
|
||||
MetaTextureSpec *pieces[META_FRAME_PIECE_LAST];
|
||||
MetaFrameLayout *layout;
|
||||
};
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_TEXTURE_DRAW_UNSCALED,
|
||||
META_TEXTURE_DRAW_SCALED_VERTICALLY,
|
||||
META_TEXTURE_DRAW_SCALED_HORIZONTALLY,
|
||||
META_TEXTURE_DRAW_SCALED_BOTH
|
||||
} MetaTextureDrawMode;
|
||||
/* FIXME dammit, these are not mutually exclusive; how to handle
|
||||
* the mess...
|
||||
*
|
||||
* normal -> noresize / vert only / horz only / both
|
||||
focused / unfocused
|
||||
* max -> focused / unfocused
|
||||
* shaded -> focused / unfocused
|
||||
* max/shaded -> focused / unfocused
|
||||
*
|
||||
* so 4 states with 8 sub-states in one, 2 sub-states in the other 3,
|
||||
* meaning 14 total
|
||||
*
|
||||
* 14 window states times 7 or 8 window types.
|
||||
*
|
||||
*
|
||||
* MetaFrameStyleSet needs rearranging to think of it this way.
|
||||
*
|
||||
*/
|
||||
META_WINDOW_STATE_MAXIMIZED,
|
||||
META_WINDOW_STATE_SHADED,
|
||||
META_WINDOW_STATE_MAXIMIZED_AND_SHADED,
|
||||
META_WINDOW_STATE_RESIZE_VERTICAL,
|
||||
META_WINDOW_STATE_RESIZE_HORIZONTAL,
|
||||
META_WINDOW_STATE_RESIZE_BOTH,
|
||||
META_WINDOW_STATE_UNFOCUSED,
|
||||
META_WINDOW_STATE_FOCUSED,
|
||||
META_WINDOW_STATE_LAST
|
||||
} MetaWindowState;
|
||||
|
||||
struct _MetaFrameStyleSet
|
||||
{
|
||||
MetaFrameStyle *styles[META_WINDOW_TYPE_LAST][META_WINDOW_STATE_LAST];
|
||||
};
|
||||
|
||||
MetaFrameLayout* meta_frame_layout_new (void);
|
||||
void meta_frame_layout_free (MetaFrameLayout *layout);
|
||||
void meta_frame_layout_get_borders (const MetaFrameLayout *layout,
|
||||
GtkWidget *widget,
|
||||
int text_height,
|
||||
MetaFrameFlags flags,
|
||||
int *top_height,
|
||||
int *bottom_height,
|
||||
int *left_width,
|
||||
int *right_width);
|
||||
void meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
|
||||
GtkWidget *widget,
|
||||
int text_height,
|
||||
@ -267,6 +313,7 @@ void meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
|
||||
int client_height,
|
||||
MetaFrameGeometry *fgeom);
|
||||
|
||||
|
||||
MetaColorSpec* meta_color_spec_new (MetaColorSpecType type);
|
||||
void meta_color_spec_free (MetaColorSpec *spec);
|
||||
void meta_color_spec_render (MetaColorSpec *spec,
|
||||
@ -296,4 +343,11 @@ void meta_texture_spec_draw (const MetaTextureSpec *desc,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
MetaFrameStyle* meta_frame_style_new (void);
|
||||
void meta_frame_style_ref (MetaFrameStyle *style);
|
||||
void meta_frame_style_unref (MetaFrameStyle *style);
|
||||
|
||||
MetaFrameStyleSet* meta_frame_style_set_new (void);
|
||||
void meta_frame_style_set_free (MetaFrameStyleSet *style_set);
|
||||
|
||||
#endif
|
||||
|
167
src/window.c
167
src/window.c
@ -1518,6 +1518,12 @@ adjust_for_gravity (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static_gravity_works (MetaDisplay *display)
|
||||
{
|
||||
return display->static_gravity_works;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_move_resize_internal (MetaWindow *window,
|
||||
MetaMoveResizeFlags flags,
|
||||
@ -1537,14 +1543,19 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
gboolean need_resize_frame = FALSE;
|
||||
int size_dx;
|
||||
int size_dy;
|
||||
int pos_dx;
|
||||
int pos_dy;
|
||||
int frame_size_dx;
|
||||
int frame_size_dy;
|
||||
gboolean is_configure_request;
|
||||
gboolean do_gravity_adjust;
|
||||
gboolean is_user_action;
|
||||
|
||||
gboolean configure_frame_first;
|
||||
gboolean use_static_gravity;
|
||||
/* used for the configure request, but may not be final
|
||||
* destination due to StaticGravity etc.
|
||||
*/
|
||||
int client_move_x;
|
||||
int client_move_y;
|
||||
|
||||
/* We don't need it in the idle queue anymore. */
|
||||
meta_window_unqueue_move_resize (window);
|
||||
|
||||
@ -1590,12 +1601,10 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
else
|
||||
new_h = window->rect.height + fgeom.top_height + fgeom.bottom_height;
|
||||
|
||||
if (new_w != window->frame->rect.width ||
|
||||
new_h != window->frame->rect.height)
|
||||
need_resize_frame = TRUE;
|
||||
|
||||
frame_size_dx = new_w - window->frame->rect.width;
|
||||
frame_size_dy = new_h - window->frame->rect.height;
|
||||
|
||||
need_resize_frame = (frame_size_dx != 0 || frame_size_dy != 0);
|
||||
|
||||
window->frame->rect.width = new_w;
|
||||
window->frame->rect.height = new_h;
|
||||
@ -1675,6 +1684,21 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* For nice effect, when growing the window we want to move/resize
|
||||
* the frame first, when shrinking the window we want to move/resize
|
||||
* the client first. If we grow one way and shrink the other,
|
||||
* see which way we're moving "more"
|
||||
*
|
||||
* Mail from Owen subject "Suggestion: Gravity and resizing from the left"
|
||||
* http://mail.gnome.org/archives/wm-spec-list/1999-November/msg00088.html
|
||||
*
|
||||
* An annoying fact you need to know in this code is that StaticGravity
|
||||
* does nothing if you _only_ resize or _only_ move the frame;
|
||||
* it must move _and_ resize, otherwise you get NorthWestGravity
|
||||
* behavior. The move and resize must actually occur, it is not
|
||||
* enough to set CWX | CWWidth but pass in the current size/pos.
|
||||
*/
|
||||
|
||||
constrain_position (window,
|
||||
window->frame ? &fgeom : NULL,
|
||||
@ -1687,41 +1711,100 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
if (window->frame)
|
||||
{
|
||||
int new_x, new_y;
|
||||
int frame_pos_dx, frame_pos_dy;
|
||||
|
||||
/* Compute new frame coords */
|
||||
new_x = root_x_nw - fgeom.left_width;
|
||||
new_y = root_y_nw - fgeom.top_height;
|
||||
|
||||
if (new_x != window->frame->rect.x ||
|
||||
new_y != window->frame->rect.y)
|
||||
need_move_frame = TRUE;
|
||||
frame_pos_dx = new_x - window->frame->rect.x;
|
||||
frame_pos_dy = new_y - window->frame->rect.y;
|
||||
|
||||
if (window->rect.x != fgeom.left_width ||
|
||||
window->rect.y != fgeom.top_height)
|
||||
need_move_client = TRUE;
|
||||
need_move_frame = (frame_pos_dx != 0 || frame_pos_dy != 0);
|
||||
|
||||
window->frame->rect.x = new_x;
|
||||
window->frame->rect.y = new_y;
|
||||
|
||||
window->frame->rect.y = new_y;
|
||||
|
||||
/* If frame will both move and resize, then StaticGravity
|
||||
* on the child window will kick in and implicitly move
|
||||
* the child with respect to the frame. The implicit
|
||||
* move will keep the child in the same place with
|
||||
* respect to the root window. If frame only moves
|
||||
* or only resizes, then the child will just move along
|
||||
* with the frame.
|
||||
*/
|
||||
|
||||
/* window->rect.x, window->rect.y are relative to frame,
|
||||
* remember they are the server coords
|
||||
*/
|
||||
pos_dx = fgeom.left_width - window->rect.x;
|
||||
pos_dy = fgeom.top_height - window->rect.y;
|
||||
|
||||
window->rect.x = fgeom.left_width;
|
||||
window->rect.y = fgeom.top_height;
|
||||
|
||||
new_x = fgeom.left_width;
|
||||
new_y = fgeom.top_height;
|
||||
|
||||
if (need_resize_frame && need_move_frame &&
|
||||
static_gravity_works (window->display))
|
||||
{
|
||||
/* static gravity kicks in because frame
|
||||
* is both moved and resized
|
||||
*/
|
||||
/* when we move the frame by frame_pos_dx, frame_pos_dy the
|
||||
* client will implicitly move relative to frame by the
|
||||
* inverse delta.
|
||||
*
|
||||
* When moving client then frame, we move the client by the
|
||||
* frame delta, to be canceled out by the implicit move by
|
||||
* the inverse frame delta, resulting in a client at new_x,
|
||||
* new_y.
|
||||
*
|
||||
* When moving frame then client, we move the client
|
||||
* by the same delta as the frame, because the client
|
||||
* was "left behind" by the frame - resulting in a client
|
||||
* at new_x, new_y.
|
||||
*
|
||||
* In both cases we need to move the client window
|
||||
* in all cases where we had to move the frame window.
|
||||
*/
|
||||
|
||||
client_move_x = new_x + frame_pos_dx;
|
||||
client_move_y = new_y + frame_pos_dy;
|
||||
|
||||
if (need_move_frame)
|
||||
need_move_client = TRUE;
|
||||
|
||||
use_static_gravity = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
client_move_x = new_x;
|
||||
client_move_y = new_y;
|
||||
|
||||
if (client_move_x != window->rect.x ||
|
||||
client_move_y != window->rect.y)
|
||||
need_move_client = TRUE;
|
||||
|
||||
use_static_gravity = FALSE;
|
||||
}
|
||||
|
||||
/* This is the final target position, but not necessarily what
|
||||
* we pass to XConfigureWindow, due to StaticGravity implicit
|
||||
* movement.
|
||||
*/
|
||||
window->rect.x = new_x;
|
||||
window->rect.y = new_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (root_x_nw != window->rect.x ||
|
||||
root_y_nw != window->rect.y)
|
||||
need_move_client = TRUE;
|
||||
|
||||
pos_dx = root_x_nw - window->rect.x;
|
||||
pos_dy = root_y_nw - window->rect.y;
|
||||
|
||||
window->rect.x = root_x_nw;
|
||||
window->rect.y = root_y_nw;
|
||||
|
||||
client_move_x = window->rect.x;
|
||||
client_move_y = window->rect.y;
|
||||
|
||||
use_static_gravity = FALSE;
|
||||
}
|
||||
|
||||
/* Fill in other frame member variables */
|
||||
@ -1736,7 +1819,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
/* See ICCCM 4.1.5 for when to send ConfigureNotify */
|
||||
|
||||
need_configure_notify = FALSE;
|
||||
|
||||
|
||||
/* If this is a configure request and we change nothing, then we
|
||||
* must send configure notify.
|
||||
*/
|
||||
@ -1756,10 +1839,30 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
/* The rest of this function syncs our new size/pos with X as
|
||||
* efficiently as possible
|
||||
*/
|
||||
if (use_static_gravity)
|
||||
{
|
||||
if ((size_dx + size_dy) >= 0)
|
||||
configure_frame_first = FALSE;
|
||||
else
|
||||
configure_frame_first = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
configure_frame_first = FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (use_static_gravity)
|
||||
meta_window_set_gravity (window, StaticGravity);
|
||||
|
||||
if (configure_frame_first && window->frame)
|
||||
meta_frame_sync_to_window (window->frame,
|
||||
resize_gravity,
|
||||
need_move_frame, need_resize_frame);
|
||||
|
||||
values.border_width = 0;
|
||||
values.x = window->rect.x;
|
||||
values.y = window->rect.y;
|
||||
values.x = client_move_x;
|
||||
values.y = client_move_y;
|
||||
values.width = window->rect.width;
|
||||
values.height = window->rect.height;
|
||||
|
||||
@ -1792,12 +1895,14 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
/* Now do the frame */
|
||||
if (window->frame)
|
||||
{
|
||||
meta_frame_sync_to_window (window->frame, need_move_frame, need_resize_frame);
|
||||
}
|
||||
if (!configure_frame_first && window->frame)
|
||||
meta_frame_sync_to_window (window->frame,
|
||||
resize_gravity,
|
||||
need_move_frame, need_resize_frame);
|
||||
|
||||
/* Put gravity back to be nice to lesser window managers */
|
||||
if (use_static_gravity)
|
||||
meta_window_set_gravity (window, NorthWestGravity);
|
||||
|
||||
if (need_configure_notify)
|
||||
send_configure_notify (window);
|
||||
|
11
src/window.h
11
src/window.h
@ -28,17 +28,6 @@
|
||||
#include <X11/Xutil.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_WINDOW_NORMAL,
|
||||
META_WINDOW_DESKTOP,
|
||||
META_WINDOW_DOCK,
|
||||
META_WINDOW_DIALOG,
|
||||
META_WINDOW_MODAL_DIALOG,
|
||||
META_WINDOW_TOOLBAR,
|
||||
META_WINDOW_MENU
|
||||
} MetaWindowType;
|
||||
|
||||
struct _MetaWindow
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
@ -10,8 +10,12 @@ test_gravity_SOURCES= \
|
||||
focus_window_SOURCES= \
|
||||
focus-window.c
|
||||
|
||||
noinst_PROGRAMS=wm-tester test-gravity focus-window
|
||||
test_resizing_SOURCES= \
|
||||
test-resizing.c
|
||||
|
||||
noinst_PROGRAMS=wm-tester test-gravity test-resizing focus-window
|
||||
|
||||
wm_tester_LDADD= @METACITY_LIBS@
|
||||
test_gravity_LDADD= @METACITY_LIBS@
|
||||
test_resizing_LDADD= @METACITY_LIBS@
|
||||
focus_window_LDADD= @METACITY_LIBS@
|
255
src/wm-tester/test-resizing.c
Normal file
255
src/wm-tester/test-resizing.c
Normal file
@ -0,0 +1,255 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
|
||||
static void
|
||||
calc_rects (XRectangle *rects, int width, int height)
|
||||
{
|
||||
int w = (width - 21) / 3;
|
||||
int h = (height - 21) / 3;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < 9)
|
||||
{
|
||||
rects[i].width = w;
|
||||
rects[i].height = h;
|
||||
++i;
|
||||
}
|
||||
|
||||
/* NW */
|
||||
rects[0].x = 0;
|
||||
rects[0].y = 0;
|
||||
|
||||
/* N */
|
||||
rects[1].x = width / 2 - w / 2;
|
||||
rects[1].y = 0;
|
||||
|
||||
/* NE */
|
||||
rects[2].x = width - w;
|
||||
rects[2].y = 0;
|
||||
|
||||
/* E */
|
||||
rects[3].x = width - w;
|
||||
rects[3].y = height / 2 - h / 2;
|
||||
|
||||
/* SE */
|
||||
rects[4].x = width - w;
|
||||
rects[4].y = height - h;
|
||||
|
||||
/* S */
|
||||
rects[5].x = width / 2 - w / 2;
|
||||
rects[5].y = height - h;
|
||||
|
||||
/* SW */
|
||||
rects[6].x = 0;
|
||||
rects[6].y = height - h;
|
||||
|
||||
/* W */
|
||||
rects[7].x = 0;
|
||||
rects[7].y = height / 2 - h / 2;
|
||||
|
||||
/* Center */
|
||||
rects[8].x = width / 2 - w / 2;
|
||||
rects[8].y = height / 2 - h / 2;
|
||||
}
|
||||
|
||||
static Bool
|
||||
all_events (Display *display,
|
||||
XEvent *event,
|
||||
XPointer arg)
|
||||
{
|
||||
return True;
|
||||
}
|
||||
|
||||
static void
|
||||
get_size (Display *d, Drawable draw,
|
||||
int *xp, int *yp, int *widthp, int *heightp)
|
||||
{
|
||||
int x, y;
|
||||
unsigned int width, height, border, depth;
|
||||
Window root;
|
||||
|
||||
XGetGeometry (d, draw, &root, &x, &y, &width, &height, &border, &depth);
|
||||
|
||||
if (xp)
|
||||
*xp = x;
|
||||
if (yp)
|
||||
*yp = y;
|
||||
if (widthp)
|
||||
*widthp = width;
|
||||
if (*heightp)
|
||||
*heightp = height;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
Display *d;
|
||||
Window w, cw;
|
||||
XSizeHints hints;
|
||||
int screen;
|
||||
XEvent ev;
|
||||
int x, y, width, height;
|
||||
Pixmap pix;
|
||||
GC gc;
|
||||
XGCValues gc_vals;
|
||||
XSetWindowAttributes set_attrs;
|
||||
XWindowChanges changes;
|
||||
XRectangle rects[9];
|
||||
gboolean redraw_pending;
|
||||
unsigned int mask;
|
||||
|
||||
d = XOpenDisplay (NULL);
|
||||
|
||||
screen = DefaultScreen (d);
|
||||
|
||||
/* Print some debug spew to show how StaticGravity works */
|
||||
w = XCreateSimpleWindow (d, RootWindow (d, screen),
|
||||
0, 0, 100, 100, 0,
|
||||
WhitePixel (d, screen),
|
||||
WhitePixel (d, screen));
|
||||
cw = XCreateSimpleWindow (d, w,
|
||||
0, 0, 100, 100, 0,
|
||||
WhitePixel (d, screen),
|
||||
WhitePixel (d, screen));
|
||||
set_attrs.win_gravity = StaticGravity;
|
||||
|
||||
XChangeWindowAttributes (d, cw,
|
||||
CWWinGravity,
|
||||
&set_attrs);
|
||||
|
||||
get_size (d, w, &x, &y, &width, &height);
|
||||
|
||||
g_print ("Parent is %d,%d %d x %d before configuring parent\n",
|
||||
x, y, width, height);
|
||||
|
||||
get_size (d, cw, &x, &y, &width, &height);
|
||||
|
||||
g_print ("Child is %d,%d %d x %d before configuring parent\n",
|
||||
x, y, width, height);
|
||||
|
||||
changes.x = 10;
|
||||
changes.y = 10;
|
||||
changes.width = 110;
|
||||
changes.height = 110;
|
||||
/* last mask wins */
|
||||
mask = CWX | CWY;
|
||||
mask = CWWidth | CWHeight;
|
||||
mask = CWX | CWY | CWWidth | CWHeight;
|
||||
|
||||
XConfigureWindow (d, w, mask, &changes);
|
||||
XSync (d, False);
|
||||
|
||||
get_size (d, w, &x, &y, &width, &height);
|
||||
|
||||
g_print ("Parent is %d,%d %d x %d after configuring parent\n",
|
||||
x, y, width, height);
|
||||
|
||||
get_size (d, cw, &x, &y, &width, &height);
|
||||
|
||||
g_print ("Child is %d,%d %d x %d after configuring parent\n",
|
||||
x, y, width, height);
|
||||
|
||||
XDestroyWindow (d, w);
|
||||
|
||||
/* The window that gets displayed */
|
||||
|
||||
x = 20;
|
||||
y = 20;
|
||||
width = 100;
|
||||
height = 100;
|
||||
|
||||
calc_rects (rects, width, height);
|
||||
|
||||
w = XCreateSimpleWindow (d, RootWindow (d, screen),
|
||||
x, y, width, height, 0,
|
||||
WhitePixel (d, screen),
|
||||
WhitePixel (d, screen));
|
||||
|
||||
set_attrs.bit_gravity = StaticGravity;
|
||||
|
||||
XChangeWindowAttributes (d, w,
|
||||
CWBitGravity,
|
||||
&set_attrs);
|
||||
|
||||
XSelectInput (d, w,
|
||||
ButtonPressMask | ExposureMask | StructureNotifyMask);
|
||||
|
||||
hints.flags = PMinSize;
|
||||
|
||||
hints.min_width = 100;
|
||||
hints.min_height = 100;
|
||||
|
||||
XSetWMNormalHints (d, w, &hints);
|
||||
XMapWindow (d, w);
|
||||
|
||||
redraw_pending = FALSE;
|
||||
while (1)
|
||||
{
|
||||
XNextEvent (d, &ev);
|
||||
|
||||
switch (ev.xany.type)
|
||||
{
|
||||
case ButtonPress:
|
||||
if (ev.xbutton.button == 3)
|
||||
{
|
||||
g_print ("Exiting on button 3 press\n");
|
||||
exit (0);
|
||||
}
|
||||
break;
|
||||
|
||||
case ConfigureNotify:
|
||||
x = ev.xconfigure.x;
|
||||
y = ev.xconfigure.y;
|
||||
width = ev.xconfigure.width;
|
||||
height = ev.xconfigure.height;
|
||||
|
||||
redraw_pending = TRUE;
|
||||
break;
|
||||
|
||||
case Expose:
|
||||
redraw_pending = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Primitive event compression */
|
||||
if (XCheckIfEvent (d, &ev, all_events, NULL))
|
||||
{
|
||||
XPutBackEvent (d, &ev);
|
||||
}
|
||||
else if (redraw_pending)
|
||||
{
|
||||
calc_rects (rects, width, height);
|
||||
|
||||
pix = XCreatePixmap (d, w, width, height,
|
||||
DefaultDepth (d, screen));
|
||||
|
||||
gc_vals.foreground = WhitePixel (d, screen);
|
||||
|
||||
gc = XCreateGC (d, pix, GCForeground, &gc_vals);
|
||||
|
||||
XFillRectangle (d, pix, gc, 0, 0, width, height);
|
||||
|
||||
/* Draw rectangles at each gravity point */
|
||||
gc_vals.foreground = BlackPixel (d, screen);
|
||||
XChangeGC (d, gc, GCForeground, &gc_vals);
|
||||
|
||||
XFillRectangles (d, pix, gc, rects, G_N_ELEMENTS (rects));
|
||||
|
||||
XCopyArea (d, pix, w, gc, 0, 0, width, height, 0, 0);
|
||||
|
||||
XFreePixmap (d, pix);
|
||||
XFreeGC (d, gc);
|
||||
|
||||
redraw_pending = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user