Drop gtk_window_move and gtk_window_get_position

These functions operate with global coordinates,
which are not available on Wayland.
This commit is contained in:
Matthias Clasen 2019-03-24 21:46:30 -04:00
parent 6f072c80db
commit 0481f123ea
4 changed files with 3 additions and 288 deletions

View File

@ -4746,7 +4746,6 @@ gtk_window_get_destroy_with_parent
gtk_window_get_icon_name
gtk_window_get_mnemonic_modifier
gtk_window_get_modal
gtk_window_get_position
gtk_window_get_role
gtk_window_get_size
gtk_window_get_title
@ -4761,7 +4760,6 @@ gtk_window_get_focus_on_map
gtk_window_get_group
gtk_window_has_group
gtk_window_get_window_type
gtk_window_move
gtk_window_resize
gtk_window_set_default_icon_name
gtk_window_set_icon_name

View File

@ -150,11 +150,8 @@ see for example <link
linkend="gtk-window-iconify">gtk_window_iconify()</link> or <link
linkend="gtk-window-maximize">gtk_window_maximize()</link> or <link
linkend="gtk-window-set-decorated">gtk_window_set_decorated()</link>.
Keep in mind that <link
linkend="gtk-window-move">gtk_window_move()</link> and window sizing
are ultimately controlled by the window manager as well and most
window managers <emphasis>will</emphasis> ignore certain requests from
time to time, in the interests of good user interface.
Keep in mind that most window managers <emphasis>will</emphasis> ignore
certain requests from time to time, in the interests of good user interface.
</para>
<!--

View File

@ -1040,8 +1040,7 @@ gtk_window_class_init (GtkWindowClass *klass)
/**
* GtkWindow:gravity:
*
* The window gravity of the window. See gtk_window_move() and #GdkGravity for
* more details about window gravity.
* The window gravity of the window.
*/
window_props[PROP_GRAVITY] =
g_param_spec_enum ("gravity",
@ -5046,277 +5045,6 @@ gtk_window_translate_csd_pos (GtkWindow *window,
}
}
/**
* gtk_window_move:
* @window: a #GtkWindow
* @x: X coordinate to move window to
* @y: Y coordinate to move window to
*
* Asks the [window manager][gtk-X11-arch] to move
* @window to the given position. Window managers are free to ignore
* this; most window managers ignore requests for initial window
* positions (instead using a user-defined placement algorithm) and
* honor requests after the window has already been shown.
*
* Note: the position is the position of the gravity-determined
* reference point for the window. The gravity determines two things:
* first, the location of the reference point in root window
* coordinates; and second, which point on the window is positioned at
* the reference point.
*
* By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
* point is simply the @x, @y supplied to gtk_window_move(). The
* top-left corner of the window decorations (aka window frame or
* border) will be placed at @x, @y. Therefore, to position a window
* at the top left of the screen, you want to use the default gravity
* (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
*
* To position a window at the bottom right corner of the screen, you
* would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
* point is at @x + the window width and @y + the window height, and
* the bottom-right corner of the window border will be placed at that
* reference point. So, to place a window in the bottom right corner
* you would first set gravity to south east, then write:
* `gtk_window_move (window, gdk_screen_width () - window_width,
* gdk_screen_height () - window_height)` (note that this
* example does not take multi-head scenarios into account).
*
* The [Extended Window Manager Hints Specification](http://www.freedesktop.org/Standards/wm-spec)
* has a nice table of gravities in the implementation notes section.
*
* The gtk_window_get_position() documentation may also be relevant.
*/
void
gtk_window_move (GtkWindow *window,
gint x,
gint y)
{
GtkWindowGeometryInfo *info;
GtkWidget *widget;
g_return_if_fail (GTK_IS_WINDOW (window));
widget = GTK_WIDGET (window);
info = gtk_window_get_geometry_info (window, TRUE);
gtk_window_translate_csd_pos (window, &x, &y, EXCLUDE_CSD_SIZE);
if (_gtk_widget_get_mapped (widget))
{
GtkAllocation allocation;
gtk_widget_get_allocation (widget, &allocation);
/* we have now sent a request with this position
* with currently-active constraints, so toggle flag.
*/
info->position_constraints_changed = FALSE;
/* we only constrain if mapped - if not mapped,
* then gtk_window_compute_configure_request()
* will apply the constraints later, and we
* don't want to lose information about
* what position the user set before then.
* i.e. if you do a move() then turn off POS_CENTER
* then show the window, your move() will work.
*/
gtk_window_constrain_position (window,
allocation.width, allocation.height,
&x, &y);
/* Note that this request doesn't go through our standard request
* framework, e.g. doesn't increment configure_request_count,
* doesn't set info->last, etc.; that's because
* we don't save the info needed to arrive at this same request
* again.
*
* To gtk_window_move_resize(), this will end up looking exactly
* the same as the position being changed by the window
* manager.
*/
gdk_surface_move (_gtk_widget_get_surface (GTK_WIDGET (window)), x, y);
}
else
{
/* Save this position to apply on mapping */
gtk_widget_queue_resize (widget);
info->initial_x = x;
info->initial_y = y;
info->initial_pos_set = TRUE;
}
}
/**
* gtk_window_get_position:
* @window: a #GtkWindow
* @root_x: (out) (optional): return location for X coordinate of
* gravity-determined reference point, or %NULL
* @root_y: (out) (optional): return location for Y coordinate of
* gravity-determined reference point, or %NULL
*
* This function returns the position you need to pass to
* gtk_window_move() to keep @window in its current position.
* This means that the meaning of the returned value varies with
* window gravity. See gtk_window_move() for more details.
*
* The reliability of this function depends on the windowing system
* currently in use. Some windowing systems, such as Wayland, do not
* support a global coordinate system, and thus the position of the
* window will always be (0, 0). Others, like X11, do not have a reliable
* way to obtain the geometry of the decorations of a window if they are
* provided by the window manager. Additionally, on X11, window manager
* have been known to mismanage window gravity, which result in windows
* moving even if you use the coordinates of the current position as
* returned by this function.
*
* If you havent changed the window gravity, its gravity will be
* #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
* gets the position of the top-left corner of the window manager
* frame for the window. gtk_window_move() sets the position of this
* same top-left corner.
*
* If a window has gravity #GDK_GRAVITY_STATIC the window manager
* frame is not relevant, and thus gtk_window_get_position() will
* always produce accurate results. However you cant use static
* gravity to do things like place a window in a corner of the screen,
* because static gravity ignores the window manager decorations.
*
* Ideally, this function should return appropriate values if the
* window has client side decorations, assuming that the windowing
* system supports global coordinates.
*
* In practice, saving the window position should not be left to
* applications, as they lack enough knowledge of the windowing
* system and the window manager state to effectively do so. The
* appropriate way to implement saving the window position is to
* use a platform-specific protocol, wherever that is available.
*/
void
gtk_window_get_position (GtkWindow *window,
gint *root_x,
gint *root_y)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
GtkWidget *widget;
GdkSurface *surface;
g_return_if_fail (GTK_IS_WINDOW (window));
widget = GTK_WIDGET (window);
surface = _gtk_widget_get_surface (widget);
if (priv->gravity == GDK_GRAVITY_STATIC)
{
if (_gtk_widget_get_mapped (widget))
{
/* This does a server round-trip, which is sort of wrong;
* but a server round-trip is inevitable for
* gdk_surface_get_frame_extents() in the usual
* NorthWestGravity case below, so not sure what else to
* do. We should likely be consistent about whether we get
* the client-side info or the server-side info.
*/
gdk_surface_get_origin (surface, root_x, root_y);
}
else
{
GdkRectangle configure_request;
gtk_window_compute_configure_request (window,
&configure_request,
NULL, NULL);
*root_x = configure_request.x;
*root_y = configure_request.y;
}
gtk_window_translate_csd_pos (window, root_x, root_y, INCLUDE_CSD_SIZE);
}
else
{
GdkRectangle frame_extents;
gint x, y;
gint w, h;
if (_gtk_widget_get_mapped (widget))
{
gdk_surface_get_frame_extents (surface, &frame_extents);
x = frame_extents.x;
y = frame_extents.y;
gtk_window_get_size (window, &w, &h);
/* gtk_window_get_size() will have already taken into account
* the padding added by the CSD shadow and title bar, so we need
* to revert it here, otherwise we'll end up counting it twice...
*/
gtk_window_update_csd_size (window, &w, &h, INCLUDE_CSD_SIZE);
}
else
{
/* We just say the frame has 0 size on all sides.
* Not sure what else to do.
*/
gtk_window_compute_configure_request (window,
&frame_extents,
NULL, NULL);
x = frame_extents.x;
y = frame_extents.y;
w = frame_extents.width;
h = frame_extents.height;
}
gtk_window_translate_csd_pos (window, &x, &y, INCLUDE_CSD_SIZE);
switch (priv->gravity)
{
case GDK_GRAVITY_NORTH:
case GDK_GRAVITY_CENTER:
case GDK_GRAVITY_SOUTH:
/* Find center of frame. */
x += frame_extents.width / 2;
/* Center client window on that point. */
x -= w / 2;
break;
case GDK_GRAVITY_SOUTH_EAST:
case GDK_GRAVITY_EAST:
case GDK_GRAVITY_NORTH_EAST:
/* Find right edge of frame */
x += frame_extents.width;
/* Align left edge of client at that point. */
x -= w;
break;
default:
break;
}
switch (priv->gravity)
{
case GDK_GRAVITY_WEST:
case GDK_GRAVITY_CENTER:
case GDK_GRAVITY_EAST:
/* Find center of frame. */
y += frame_extents.height / 2;
/* Center client window there. */
y -= h / 2;
break;
case GDK_GRAVITY_SOUTH_WEST:
case GDK_GRAVITY_SOUTH:
case GDK_GRAVITY_SOUTH_EAST:
/* Find south edge of frame */
y += frame_extents.height;
/* Place bottom edge of client there */
y -= h;
break;
default:
break;
}
if (root_x)
*root_x = x;
if (root_y)
*root_y = y;
}
}
static void
gtk_window_destroy (GtkWidget *widget)
{

View File

@ -384,14 +384,6 @@ GDK_AVAILABLE_IN_ALL
void gtk_window_get_size (GtkWindow *window,
gint *width,
gint *height);
GDK_AVAILABLE_IN_ALL
void gtk_window_move (GtkWindow *window,
gint x,
gint y);
GDK_AVAILABLE_IN_ALL
void gtk_window_get_position (GtkWindow *window,
gint *root_x,
gint *root_y);
GDK_AVAILABLE_IN_ALL
GtkWindowGroup *gtk_window_get_group (GtkWindow *window);