Compare commits
21 Commits
3.13.2
...
wip/xtogls
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ac563307e | ||
|
|
24956fadcc | ||
|
|
fc5de438b5 | ||
|
|
94cee3ef09 | ||
|
|
1e6b042778 | ||
|
|
048f035d30 | ||
|
|
b32c837df9 | ||
|
|
dd03a76d51 | ||
|
|
806a666950 | ||
|
|
b240a5e819 | ||
|
|
fe823b3553 | ||
|
|
d380d30ef4 | ||
|
|
1fe5b3e7d5 | ||
|
|
a8df208a5c | ||
|
|
f3f3c94831 | ||
|
|
6e06648f7a | ||
|
|
afb41f715b | ||
|
|
19d26dde92 | ||
|
|
4acb902423 | ||
|
|
626516d12e | ||
|
|
1c94df2553 |
13
configure.ac
13
configure.ac
@@ -199,9 +199,15 @@ AS_IF([test "x$WAYLAND_SCANNER" = "xno"],
|
||||
AC_SUBST([WAYLAND_SCANNER])
|
||||
AC_SUBST(XWAYLAND_PATH)
|
||||
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0 wayland-server >= 1.4.93 libdrm libsystemd"
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0 wayland-server >= 1.4.93"
|
||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [libdrm libsystemd], [have_native_backend=yes], [have_native_backend=no])
|
||||
if test $have_native_backend = yes; then
|
||||
AC_DEFINE([HAVE_NATIVE_BACKEND],[1],[Define if you want to enable the native (KMS) backend based on systemd])
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test $have_native_backend = yes])
|
||||
|
||||
PKG_CHECK_EXISTS([xi >= 1.6.99.1],
|
||||
AC_DEFINE([HAVE_XI23],[1],[Define if you have support for XInput 2.3 or greater]))
|
||||
|
||||
@@ -318,6 +324,11 @@ fi
|
||||
|
||||
GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
|
||||
|
||||
AC_CHECK_DECL([GL_EXT_x11_sync_object],
|
||||
[],
|
||||
[AC_MSG_ERROR([GL_EXT_x11_sync_object definition not found, please update your GL headers])],
|
||||
[#include <GL/glx.h>])
|
||||
|
||||
#### Warnings (last since -Werror can disturb other tests)
|
||||
|
||||
# Stay command-line compatible with the gnome-common configure option. Here
|
||||
|
||||
@@ -11,6 +11,7 @@ INCLUDES= \
|
||||
-DCOGL_ENABLE_EXPERIMENTAL_API \
|
||||
-DCOGL_ENABLE_EXPERIMENTAL_2_0_API \
|
||||
$(MUTTER_CFLAGS) \
|
||||
$(MUTTER_NATIVE_BACKEND_CFLAGS) \
|
||||
-I$(srcdir) \
|
||||
-I$(srcdir)/backends \
|
||||
-I$(srcdir)/core \
|
||||
@@ -71,18 +72,6 @@ libmutter_la_SOURCES = \
|
||||
backends/meta-monitor-manager-dummy.h \
|
||||
backends/edid-parse.c \
|
||||
backends/edid.h \
|
||||
backends/native/meta-backend-native.c \
|
||||
backends/native/meta-backend-native.h \
|
||||
backends/native/meta-cursor-renderer-native.c \
|
||||
backends/native/meta-cursor-renderer-native.h \
|
||||
backends/native/meta-idle-monitor-native.c \
|
||||
backends/native/meta-idle-monitor-native.h \
|
||||
backends/native/meta-monitor-manager-kms.c \
|
||||
backends/native/meta-monitor-manager-kms.h \
|
||||
backends/native/meta-launcher.c \
|
||||
backends/native/meta-launcher.h \
|
||||
backends/native/dbus-utils.c \
|
||||
backends/native/dbus-utils.h \
|
||||
backends/x11/meta-backend-x11.c \
|
||||
backends/x11/meta-backend-x11.h \
|
||||
backends/x11/meta-cursor-renderer-x11.c \
|
||||
@@ -129,6 +118,8 @@ libmutter_la_SOURCES = \
|
||||
compositor/meta-surface-actor-wayland.h \
|
||||
compositor/meta-stage.h \
|
||||
compositor/meta-stage.c \
|
||||
compositor/meta-sync-ring.c \
|
||||
compositor/meta-sync-ring.h \
|
||||
compositor/meta-texture-rectangle.c \
|
||||
compositor/meta-texture-rectangle.h \
|
||||
compositor/meta-texture-tower.c \
|
||||
@@ -243,11 +234,27 @@ libmutter_la_SOURCES = \
|
||||
wayland/window-wayland.c \
|
||||
wayland/window-wayland.h
|
||||
|
||||
if HAVE_NATIVE_BACKEND
|
||||
libmutter_la_SOURCES += \
|
||||
backends/native/meta-backend-native.c \
|
||||
backends/native/meta-backend-native.h \
|
||||
backends/native/meta-cursor-renderer-native.c \
|
||||
backends/native/meta-cursor-renderer-native.h \
|
||||
backends/native/meta-idle-monitor-native.c \
|
||||
backends/native/meta-idle-monitor-native.h \
|
||||
backends/native/meta-monitor-manager-kms.c \
|
||||
backends/native/meta-monitor-manager-kms.h \
|
||||
backends/native/meta-launcher.c \
|
||||
backends/native/meta-launcher.h \
|
||||
backends/native/dbus-utils.c \
|
||||
backends/native/dbus-utils.h
|
||||
endif
|
||||
|
||||
nodist_libmutter_la_SOURCES = \
|
||||
$(mutter_built_sources)
|
||||
|
||||
libmutter_la_LDFLAGS = -no-undefined
|
||||
libmutter_la_LIBADD = $(MUTTER_LIBS)
|
||||
libmutter_la_LIBADD = $(MUTTER_LIBS) $(MUTTER_NATIVE_BACKEND_LIBS)
|
||||
|
||||
# Headers installed for plugins; introspected information will
|
||||
# be extracted into Mutter-<version>.gir
|
||||
|
||||
@@ -30,7 +30,10 @@
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#endif
|
||||
|
||||
static MetaBackend *_backend;
|
||||
|
||||
@@ -214,7 +217,7 @@ get_backend_type (void)
|
||||
return META_TYPE_BACKEND_X11;
|
||||
#endif
|
||||
|
||||
#if defined(CLUTTER_WINDOWING_EGL)
|
||||
#if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND)
|
||||
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
|
||||
return META_TYPE_BACKEND_NATIVE;
|
||||
#endif
|
||||
|
||||
@@ -28,7 +28,10 @@
|
||||
#include "display-private.h"
|
||||
#include "screen-private.h"
|
||||
#include "meta-backend.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-cursor-renderer-native.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -171,13 +174,15 @@ meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
|
||||
static struct gbm_device *
|
||||
get_gbm_device (void)
|
||||
{
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
MetaBackend *meta_backend = meta_get_backend ();
|
||||
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
|
||||
|
||||
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
|
||||
return meta_cursor_renderer_native_get_gbm_device (META_CURSOR_RENDERER_NATIVE (renderer));
|
||||
else
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -210,9 +210,9 @@ make_watch (MetaIdleMonitor *monitor,
|
||||
* meta_idle_monitor_add_idle_watch:
|
||||
* @monitor: A #MetaIdleMonitor
|
||||
* @interval_msec: The idletime interval, in milliseconds
|
||||
* @callback: (allow-none): The callback to call when the user has
|
||||
* @callback: (nullable): The callback to call when the user has
|
||||
* accumulated @interval_msec milliseconds of idle time.
|
||||
* @user_data: (allow-none): The user data to pass to the callback
|
||||
* @user_data: (nullable): The user data to pass to the callback
|
||||
* @notify: A #GDestroyNotify
|
||||
*
|
||||
* Returns: a watch id
|
||||
@@ -252,9 +252,9 @@ meta_idle_monitor_add_idle_watch (MetaIdleMonitor *monitor,
|
||||
/**
|
||||
* meta_idle_monitor_add_user_active_watch:
|
||||
* @monitor: A #MetaIdleMonitor
|
||||
* @callback: (allow-none): The callback to call when the user is
|
||||
* @callback: (nullable): The callback to call when the user is
|
||||
* active again.
|
||||
* @user_data: (allow-none): The user data to pass to the callback
|
||||
* @user_data: (nullable): The user data to pass to the callback
|
||||
* @notify: A #GDestroyNotify
|
||||
*
|
||||
* Returns: a watch id
|
||||
|
||||
@@ -68,7 +68,7 @@ meta_create_color_texture_4ub (guint8 red,
|
||||
|
||||
/**
|
||||
* meta_create_texture_pipeline:
|
||||
* @src_texture: (allow-none): texture to use initially for the layer
|
||||
* @src_texture: (nullable): texture to use initially for the layer
|
||||
*
|
||||
* Creates a pipeline with a single layer. Using a common template
|
||||
* makes it easier for Cogl to share a shader for different uses in
|
||||
|
||||
@@ -15,7 +15,8 @@ struct _MetaCompositor
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
guint repaint_func_id;
|
||||
guint pre_paint_func_id;
|
||||
guint post_paint_func_id;
|
||||
|
||||
gint64 server_time_query_time;
|
||||
gint64 server_time_offset;
|
||||
@@ -38,6 +39,9 @@ struct _MetaCompositor
|
||||
gint switch_workspace_in_progress;
|
||||
|
||||
MetaPluginManager *plugin_mgr;
|
||||
|
||||
gboolean frame_has_updated_xsurfaces;
|
||||
gboolean have_x11_sync_object;
|
||||
};
|
||||
|
||||
/* Wait 2ms after vblank before starting to draw next frame */
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#include "frame.h"
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#include "meta-sync-ring.h"
|
||||
|
||||
#include "backends/meta-backend.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
@@ -136,7 +137,11 @@ meta_switch_workspace_completed (MetaCompositor *compositor)
|
||||
void
|
||||
meta_compositor_destroy (MetaCompositor *compositor)
|
||||
{
|
||||
clutter_threads_remove_repaint_func (compositor->repaint_func_id);
|
||||
clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
|
||||
clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
|
||||
|
||||
if (compositor->have_x11_sync_object)
|
||||
meta_sync_ring_destroy ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -146,6 +151,8 @@ process_damage (MetaCompositor *compositor,
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
meta_window_actor_process_x11_damage (window_actor, event);
|
||||
|
||||
compositor->frame_has_updated_xsurfaces = TRUE;
|
||||
}
|
||||
|
||||
static Window
|
||||
@@ -569,6 +576,8 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
* contents until we show the stage.
|
||||
*/
|
||||
XMapWindow (xdisplay, compositor->output);
|
||||
|
||||
compositor->have_x11_sync_object = meta_sync_ring_init (display);
|
||||
}
|
||||
|
||||
redirect_windows (display->screen);
|
||||
@@ -595,7 +604,7 @@ meta_compositor_unmanage (MetaCompositor *compositor)
|
||||
/**
|
||||
* meta_shape_cow_for_window:
|
||||
* @compositor: A #MetaCompositor
|
||||
* @window: (allow-none): A #MetaWindow to shape the COW for
|
||||
* @window: (nullable): A #MetaWindow to shape the COW for
|
||||
*
|
||||
* Sets an bounding shape on the COW so that the given window
|
||||
* is exposed. If @window is %NULL it clears the shape again.
|
||||
@@ -780,6 +789,10 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
if (!meta_is_wayland_compositor () && event->type == MapNotify)
|
||||
clutter_x11_handle_event (event);
|
||||
|
||||
if (compositor->have_x11_sync_object &&
|
||||
event->type == (compositor->display->xsync_event_base + XSyncAlarmNotify))
|
||||
meta_sync_ring_handle_event ((XSyncAlarmNotifyEvent *) event);
|
||||
|
||||
/* The above handling is basically just "observing" the events, so we return
|
||||
* FALSE to indicate that the event should not be filtered out; if we have
|
||||
* GTK+ windows in the same process, GTK+ needs the ConfigureNotify event, for example.
|
||||
@@ -1125,11 +1138,12 @@ frame_callback (CoglOnscreen *onscreen,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pre_paint_windows (MetaCompositor *compositor)
|
||||
static gboolean
|
||||
meta_pre_paint_func (gpointer data)
|
||||
{
|
||||
GList *l;
|
||||
MetaWindowActor *top_window;
|
||||
MetaCompositor *compositor = data;
|
||||
|
||||
if (compositor->onscreen == NULL)
|
||||
{
|
||||
@@ -1141,7 +1155,7 @@ pre_paint_windows (MetaCompositor *compositor)
|
||||
}
|
||||
|
||||
if (compositor->windows == NULL)
|
||||
return;
|
||||
return TRUE;
|
||||
|
||||
top_window = g_list_last (compositor->windows)->data;
|
||||
|
||||
@@ -1153,13 +1167,53 @@ pre_paint_windows (MetaCompositor *compositor)
|
||||
|
||||
for (l = compositor->windows; l; l = l->next)
|
||||
meta_window_actor_pre_paint (l->data);
|
||||
|
||||
if (compositor->frame_has_updated_xsurfaces)
|
||||
{
|
||||
/* We need to make sure that any X drawing that happens before
|
||||
* the XDamageSubtract() for each window above is visible to
|
||||
* subsequent GL rendering; the standardized way to do this is
|
||||
* GL_EXT_X11_sync_object. Since this isn't implemented yet in
|
||||
* mesa, we also have a path that relies on the implementation
|
||||
* of the open source drivers.
|
||||
*
|
||||
* Anything else, we just hope for the best.
|
||||
*
|
||||
* Xorg and open source driver specifics:
|
||||
*
|
||||
* The X server makes sure to flush drawing to the kernel before
|
||||
* sending out damage events, but since we use
|
||||
* DamageReportBoundingBox there may be drawing between the last
|
||||
* damage event and the XDamageSubtract() that needs to be
|
||||
* flushed as well.
|
||||
*
|
||||
* Xorg always makes sure that drawing is flushed to the kernel
|
||||
* before writing events or responses to the client, so any
|
||||
* round trip request at this point is sufficient to flush the
|
||||
* GLX buffers.
|
||||
*/
|
||||
if (compositor->have_x11_sync_object)
|
||||
compositor->have_x11_sync_object = meta_sync_ring_insert_wait ();
|
||||
else
|
||||
XSync (compositor->display->xdisplay, False);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_repaint_func (gpointer data)
|
||||
meta_post_paint_func (gpointer data)
|
||||
{
|
||||
MetaCompositor *compositor = data;
|
||||
pre_paint_windows (compositor);
|
||||
|
||||
if (compositor->frame_has_updated_xsurfaces)
|
||||
{
|
||||
if (compositor->have_x11_sync_object)
|
||||
compositor->have_x11_sync_object = meta_sync_ring_after_frame ();
|
||||
|
||||
compositor->frame_has_updated_xsurfaces = FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1198,10 +1252,16 @@ meta_compositor_new (MetaDisplay *display)
|
||||
G_CALLBACK (on_shadow_factory_changed),
|
||||
compositor);
|
||||
|
||||
compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
|
||||
compositor->pre_paint_func_id =
|
||||
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT,
|
||||
meta_pre_paint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
compositor->post_paint_func_id =
|
||||
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
|
||||
meta_post_paint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
return compositor;
|
||||
}
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@ meta_shadow_unref (MetaShadow *shadow)
|
||||
* @window_y: y position of the region to paint a shadow for
|
||||
* @window_width: actual width of the region to paint a shadow for
|
||||
* @window_height: actual height of the region to paint a shadow for
|
||||
* @clip: (allow-none): if non-%NULL specifies the visible portion
|
||||
* @clip: (nullable): if non-%NULL specifies the visible portion
|
||||
* of the shadow.
|
||||
* @clip_strictly: if %TRUE, drawing will be clipped strictly
|
||||
* to @clip, otherwise, it will be only used to optimize
|
||||
|
||||
@@ -238,26 +238,6 @@ meta_surface_actor_x11_pre_paint (MetaSurfaceActor *actor)
|
||||
XDamageSubtract (xdisplay, priv->damage, None, None);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
/* We need to make sure that any X drawing that happens before the
|
||||
* XDamageSubtract() above is visible to subsequent GL rendering;
|
||||
* the only standardized way to do this is EXT_x11_sync_object,
|
||||
* which isn't yet widely available. For now, we count on details
|
||||
* of Xorg and the open source drivers, and hope for the best
|
||||
* otherwise.
|
||||
*
|
||||
* Xorg and open source driver specifics:
|
||||
*
|
||||
* The X server makes sure to flush drawing to the kernel before
|
||||
* sending out damage events, but since we use DamageReportBoundingBox
|
||||
* there may be drawing between the last damage event and the
|
||||
* XDamageSubtract() that needs to be flushed as well.
|
||||
*
|
||||
* Xorg always makes sure that drawing is flushed to the kernel
|
||||
* before writing events or responses to the client, so any round trip
|
||||
* request at this point is sufficient to flush the GLX buffers.
|
||||
*/
|
||||
XSync (xdisplay, False);
|
||||
|
||||
priv->received_damage = FALSE;
|
||||
}
|
||||
|
||||
|
||||
574
src/compositor/meta-sync-ring.c
Normal file
574
src/compositor/meta-sync-ring.c
Normal file
@@ -0,0 +1,574 @@
|
||||
/*
|
||||
* This is based on an original C++ implementation for compiz that
|
||||
* carries the following copyright notice:
|
||||
*
|
||||
*
|
||||
* Copyright © 2011 NVIDIA Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of NVIDIA
|
||||
* Corporation not be used in advertising or publicity pertaining to
|
||||
* distribution of the software without specific, written prior
|
||||
* permission. NVIDIA Corporation makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Authors: James Jones <jajones@nvidia.com>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include <meta/display.h>
|
||||
#include <meta/util.h>
|
||||
|
||||
#include "meta-sync-ring.h"
|
||||
|
||||
/* Theory of operation:
|
||||
*
|
||||
* We use a ring of NUM_SYNCS fence objects. On each frame we advance
|
||||
* to the next fence in the ring. For each fence we do:
|
||||
*
|
||||
* 1. fence is XSyncTriggerFence()'d and glWaitSync()'d
|
||||
* 2. NUM_SYNCS / 2 frames later, fence should be triggered
|
||||
* 3. fence is XSyncResetFence()'d
|
||||
* 4. NUM_SYNCS / 2 frames later, fence should be reset
|
||||
* 5. go back to 1 and re-use fence
|
||||
*
|
||||
* glClientWaitSync() and XAlarms are used in steps 2 and 4,
|
||||
* respectively, to double-check the expectections.
|
||||
*/
|
||||
|
||||
#define NUM_SYNCS 10
|
||||
#define MAX_SYNC_WAIT_TIME (1 * 1000 * 1000 * 1000) /* one sec */
|
||||
#define MAX_REBOOT_ATTEMPTS 2
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_SYNC_STATE_READY,
|
||||
META_SYNC_STATE_WAITING,
|
||||
META_SYNC_STATE_DONE,
|
||||
META_SYNC_STATE_RESET_PENDING,
|
||||
} MetaSyncState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Display *xdisplay;
|
||||
|
||||
XSyncFence xfence;
|
||||
GLsync glsync;
|
||||
|
||||
XSyncCounter xcounter;
|
||||
XSyncAlarm xalarm;
|
||||
XSyncValue next_counter_value;
|
||||
|
||||
MetaSyncState state;
|
||||
} MetaSync;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
GHashTable *alarm_to_sync;
|
||||
|
||||
MetaSync *syncs_array[NUM_SYNCS];
|
||||
guint current_sync_idx;
|
||||
MetaSync *current_sync;
|
||||
guint warmup_syncs;
|
||||
|
||||
guint reboots;
|
||||
} MetaSyncRing;
|
||||
|
||||
static MetaSyncRing meta_sync_ring = { 0 };
|
||||
|
||||
static XSyncValue SYNC_VALUE_ZERO;
|
||||
static XSyncValue SYNC_VALUE_ONE;
|
||||
|
||||
static void (*meta_gl_get_integerv) (GLenum pname,
|
||||
GLint *params);
|
||||
static const char* (*meta_gl_get_stringi) (GLenum name,
|
||||
GLuint index);
|
||||
static void (*meta_gl_delete_sync) (GLsync sync);
|
||||
static GLenum (*meta_gl_client_wait_sync) (GLsync sync,
|
||||
GLbitfield flags,
|
||||
GLuint64 timeout);
|
||||
static void (*meta_gl_wait_sync) (GLsync sync,
|
||||
GLbitfield flags,
|
||||
GLuint64 timeout);
|
||||
static GLsync (*meta_gl_import_sync) (GLenum external_sync_type,
|
||||
GLintptr external_sync,
|
||||
GLbitfield flags);
|
||||
|
||||
static GLenum (*meta_gl_get_error) (void);
|
||||
static GLboolean (*meta_gl_is_sync) (GLsync sync);
|
||||
|
||||
static MetaSyncRing *
|
||||
meta_sync_ring_get (void)
|
||||
{
|
||||
if (meta_sync_ring.reboots > MAX_REBOOT_ATTEMPTS)
|
||||
return NULL;
|
||||
|
||||
return &meta_sync_ring;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_gl_symbol (const char *name,
|
||||
void **func)
|
||||
{
|
||||
*func = cogl_get_proc_address (name);
|
||||
if (!*func)
|
||||
{
|
||||
meta_verbose ("MetaSyncRing: failed to resolve required GL symbol \"%s\"\n", name);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_gl_extensions (void)
|
||||
{
|
||||
int num_extensions, i;
|
||||
gboolean sync = FALSE;
|
||||
gboolean x11_sync_object = FALSE;
|
||||
|
||||
meta_gl_get_integerv (GL_NUM_EXTENSIONS, &num_extensions);
|
||||
|
||||
for (i = 0; i < num_extensions; ++i)
|
||||
{
|
||||
const char *ext = meta_gl_get_stringi (GL_EXTENSIONS, i);
|
||||
|
||||
if (g_strcmp0 ("GL_ARB_sync", ext) == 0)
|
||||
sync = TRUE;
|
||||
else if (g_strcmp0 ("GL_EXT_x11_sync_object", ext) == 0)
|
||||
x11_sync_object = TRUE;
|
||||
}
|
||||
|
||||
return sync && x11_sync_object;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_required_symbols (void)
|
||||
{
|
||||
static gboolean success = FALSE;
|
||||
|
||||
if (success)
|
||||
return TRUE;
|
||||
|
||||
/* We don't link against libGL directly because cogl may want to
|
||||
* use something else. This assumes that cogl has been initialized
|
||||
* and dynamically loaded libGL at this point.
|
||||
*/
|
||||
|
||||
if (!load_gl_symbol ("glGetIntegerv", (void **) &meta_gl_get_integerv))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glGetStringi", (void **) &meta_gl_get_stringi))
|
||||
goto out;
|
||||
|
||||
if (!check_gl_extensions ())
|
||||
{
|
||||
meta_verbose ("MetaSyncRing: couldn't find required GL extensions\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!load_gl_symbol ("glDeleteSync", (void **) &meta_gl_delete_sync))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glClientWaitSync", (void **) &meta_gl_client_wait_sync))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glWaitSync", (void **) &meta_gl_wait_sync))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync))
|
||||
goto out;
|
||||
|
||||
if (!load_gl_symbol ("glGetError", (void **) &meta_gl_get_error))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glIsSync", (void **) &meta_gl_is_sync))
|
||||
goto out;
|
||||
|
||||
success = TRUE;
|
||||
out:
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
print_gl_error (void)
|
||||
{
|
||||
GLenum e;
|
||||
switch (e = meta_gl_get_error ())
|
||||
{
|
||||
case GL_NO_ERROR:
|
||||
meta_warning ("GL_NO_ERROR\n");
|
||||
break;
|
||||
case GL_INVALID_ENUM:
|
||||
meta_warning ("GL_INVALID_ENUM\n");
|
||||
break;
|
||||
case GL_INVALID_VALUE:
|
||||
meta_warning ("GL_INVALID_VALUE\n");
|
||||
break;
|
||||
case GL_INVALID_OPERATION:
|
||||
meta_warning ("GL_INVALID_OPERATION\n");
|
||||
break;
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||
meta_warning ("GL_INVALID_FRAMEBUFFER_OPERATION\n");
|
||||
break;
|
||||
case GL_OUT_OF_MEMORY:
|
||||
meta_warning ("GL_OUT_OF_MEMORY\n");
|
||||
break;
|
||||
case GL_STACK_OVERFLOW:
|
||||
meta_warning ("GL_STACK_OVERFLOW\n");
|
||||
break;
|
||||
case GL_STACK_UNDERFLOW:
|
||||
meta_warning ("GL_STACK_UNDERFLOW\n");
|
||||
break;
|
||||
default:
|
||||
meta_warning ("GL error 0x%x\n", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_insert (MetaSync *self)
|
||||
{
|
||||
g_return_if_fail (self->state == META_SYNC_STATE_READY);
|
||||
|
||||
XSyncTriggerFence (self->xdisplay, self->xfence);
|
||||
XFlush (self->xdisplay);
|
||||
|
||||
meta_gl_wait_sync (self->glsync, 0, GL_TIMEOUT_IGNORED);
|
||||
|
||||
self->state = META_SYNC_STATE_WAITING;
|
||||
}
|
||||
|
||||
static GLenum
|
||||
meta_sync_check_update_finished (MetaSync *self,
|
||||
GLuint64 timeout)
|
||||
{
|
||||
GLenum status = GL_WAIT_FAILED;
|
||||
|
||||
switch (self->state)
|
||||
{
|
||||
case META_SYNC_STATE_DONE:
|
||||
status = GL_ALREADY_SIGNALED;
|
||||
break;
|
||||
case META_SYNC_STATE_WAITING:
|
||||
status = meta_gl_client_wait_sync (self->glsync, 0, timeout);
|
||||
if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED)
|
||||
self->state = META_SYNC_STATE_DONE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_warn_if_fail (status != GL_WAIT_FAILED);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_reset (MetaSync *self)
|
||||
{
|
||||
XSyncAlarmAttributes attrs;
|
||||
int overflow;
|
||||
|
||||
g_return_if_fail (self->state == META_SYNC_STATE_DONE);
|
||||
|
||||
XSyncResetFence (self->xdisplay, self->xfence);
|
||||
|
||||
attrs.trigger.wait_value = self->next_counter_value;
|
||||
|
||||
XSyncChangeAlarm (self->xdisplay, self->xalarm, XSyncCAValue, &attrs);
|
||||
XSyncSetCounter (self->xdisplay, self->xcounter, self->next_counter_value);
|
||||
|
||||
XSyncValueAdd (&self->next_counter_value,
|
||||
self->next_counter_value,
|
||||
SYNC_VALUE_ONE,
|
||||
&overflow);
|
||||
|
||||
self->state = META_SYNC_STATE_RESET_PENDING;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_handle_event (MetaSync *self,
|
||||
XSyncAlarmNotifyEvent *event)
|
||||
{
|
||||
g_return_if_fail (event->alarm == self->xalarm);
|
||||
g_return_if_fail (self->state == META_SYNC_STATE_RESET_PENDING);
|
||||
|
||||
self->state = META_SYNC_STATE_READY;
|
||||
}
|
||||
|
||||
static MetaSync *
|
||||
meta_sync_new (Display *xdisplay)
|
||||
{
|
||||
MetaSync *self;
|
||||
XSyncAlarmAttributes attrs;
|
||||
|
||||
self = g_malloc0 (sizeof (MetaSync));
|
||||
|
||||
self->xdisplay = xdisplay;
|
||||
|
||||
self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE);
|
||||
meta_warning ("created X fence 0x%x\n", self->xfence);
|
||||
self->glsync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0);
|
||||
print_gl_error ();
|
||||
|
||||
self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO);
|
||||
|
||||
attrs.trigger.counter = self->xcounter;
|
||||
attrs.trigger.value_type = XSyncAbsolute;
|
||||
attrs.trigger.wait_value = SYNC_VALUE_ONE;
|
||||
attrs.trigger.test_type = XSyncPositiveTransition;
|
||||
attrs.events = TRUE;
|
||||
self->xalarm = XSyncCreateAlarm (xdisplay,
|
||||
XSyncCACounter |
|
||||
XSyncCAValueType |
|
||||
XSyncCAValue |
|
||||
XSyncCATestType |
|
||||
XSyncCAEvents,
|
||||
&attrs);
|
||||
|
||||
XSyncIntToValue (&self->next_counter_value, 1);
|
||||
|
||||
self->state = META_SYNC_STATE_READY;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static Bool
|
||||
alarm_event_predicate (Display *dpy,
|
||||
XEvent *event,
|
||||
XPointer data)
|
||||
{
|
||||
int xsync_event_base;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return False;
|
||||
|
||||
xsync_event_base = meta_display_get_sync_event_base (ring->display);
|
||||
|
||||
if (event->type == xsync_event_base + XSyncAlarmNotify)
|
||||
{
|
||||
if (((MetaSync *) data)->xalarm == ((XSyncAlarmNotifyEvent *) event)->alarm)
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_free (MetaSync *self)
|
||||
{
|
||||
/* When our assumptions don't hold, something has gone wrong but we
|
||||
* don't know what, so we reboot the ring. While doing that, we
|
||||
* trigger fences before deleting them to try to get ourselves out
|
||||
* of a potentially stuck GPU state.
|
||||
*/
|
||||
switch (self->state)
|
||||
{
|
||||
case META_SYNC_STATE_WAITING:
|
||||
case META_SYNC_STATE_DONE:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case META_SYNC_STATE_RESET_PENDING:
|
||||
{
|
||||
XEvent event;
|
||||
XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self);
|
||||
meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event);
|
||||
}
|
||||
/* fall through */
|
||||
case META_SYNC_STATE_READY:
|
||||
XSyncTriggerFence (self->xdisplay, self->xfence);
|
||||
XFlush (self->xdisplay);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
meta_gl_delete_sync (self->glsync);
|
||||
XSyncDestroyFence (self->xdisplay, self->xfence);
|
||||
XSyncDestroyCounter (self->xdisplay, self->xcounter);
|
||||
XSyncDestroyAlarm (self->xdisplay, self->xalarm);
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_sync_ring_init (MetaDisplay *display)
|
||||
{
|
||||
guint i;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
g_return_val_if_fail (display != NULL, FALSE);
|
||||
g_return_val_if_fail (ring->display == NULL, FALSE);
|
||||
|
||||
if (!load_required_symbols ())
|
||||
return FALSE;
|
||||
|
||||
if (!meta_display_has_sync (display))
|
||||
return FALSE;
|
||||
|
||||
print_gl_error ();
|
||||
|
||||
XSyncIntToValue (&SYNC_VALUE_ZERO, 0);
|
||||
XSyncIntToValue (&SYNC_VALUE_ONE, 1);
|
||||
|
||||
ring->display = display;
|
||||
|
||||
ring->alarm_to_sync = g_hash_table_new (NULL, NULL);
|
||||
|
||||
for (i = 0; i < NUM_SYNCS; ++i)
|
||||
{
|
||||
MetaSync *sync = meta_sync_new (meta_display_get_xdisplay (display));
|
||||
ring->syncs_array[i] = sync;
|
||||
g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync);
|
||||
}
|
||||
|
||||
ring->current_sync_idx = 0;
|
||||
ring->current_sync = ring->syncs_array[0];
|
||||
ring->warmup_syncs = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_sync_ring_destroy (void)
|
||||
{
|
||||
guint i;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return;
|
||||
|
||||
g_return_if_fail (ring->display != NULL);
|
||||
|
||||
ring->current_sync_idx = 0;
|
||||
ring->current_sync = NULL;
|
||||
ring->warmup_syncs = 0;
|
||||
|
||||
for (i = 0; i < NUM_SYNCS; ++i)
|
||||
meta_sync_free (ring->syncs_array[i]);
|
||||
|
||||
g_hash_table_destroy (ring->alarm_to_sync);
|
||||
|
||||
ring->display = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_sync_ring_reboot (MetaDisplay *display)
|
||||
{
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
meta_sync_ring_destroy ();
|
||||
|
||||
ring->reboots += 1;
|
||||
|
||||
if (!meta_sync_ring_get ())
|
||||
{
|
||||
meta_warning ("MetaSyncRing: Too many reboots -- disabling\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return meta_sync_ring_init (display);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_sync_ring_after_frame (void)
|
||||
{
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
g_return_if_fail (ring->display != NULL);
|
||||
|
||||
if (ring->warmup_syncs >= NUM_SYNCS / 2)
|
||||
{
|
||||
guint reset_sync_idx = (ring->current_sync_idx + NUM_SYNCS - (NUM_SYNCS / 2)) % NUM_SYNCS;
|
||||
MetaSync *sync_to_reset = ring->syncs_array[reset_sync_idx];
|
||||
|
||||
GLenum status = meta_sync_check_update_finished (sync_to_reset, 0);
|
||||
if (status == GL_TIMEOUT_EXPIRED)
|
||||
{
|
||||
meta_warning ("MetaSyncRing: We should never wait for a sync -- add more syncs?\n");
|
||||
status = meta_sync_check_update_finished (sync_to_reset, MAX_SYNC_WAIT_TIME);
|
||||
}
|
||||
|
||||
if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED)
|
||||
{
|
||||
meta_warning ("MetaSyncRing: Timed out waiting for sync object.\n");
|
||||
return meta_sync_ring_reboot (ring->display);
|
||||
}
|
||||
|
||||
meta_sync_reset (sync_to_reset);
|
||||
}
|
||||
else
|
||||
{
|
||||
ring->warmup_syncs += 1;
|
||||
}
|
||||
|
||||
ring->current_sync_idx += 1;
|
||||
ring->current_sync_idx %= NUM_SYNCS;
|
||||
|
||||
ring->current_sync = ring->syncs_array[ring->current_sync_idx];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_sync_ring_insert_wait (void)
|
||||
{
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
g_return_if_fail (ring->display != NULL);
|
||||
|
||||
if (ring->current_sync->state != META_SYNC_STATE_READY)
|
||||
{
|
||||
meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?\n");
|
||||
if (!meta_sync_ring_reboot (ring->display))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
meta_sync_insert (ring->current_sync);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_sync_ring_handle_event (XSyncAlarmNotifyEvent *event)
|
||||
{
|
||||
MetaSync *sync;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return;
|
||||
|
||||
g_return_if_fail (ring->display != NULL);
|
||||
|
||||
sync = g_hash_table_lookup (ring->alarm_to_sync, (gpointer) event->alarm);
|
||||
if (sync)
|
||||
meta_sync_handle_event (sync, event);
|
||||
}
|
||||
17
src/compositor/meta-sync-ring.h
Normal file
17
src/compositor/meta-sync-ring.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _META_SYNC_RING_H_
|
||||
#define _META_SYNC_RING_H_
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/sync.h>
|
||||
|
||||
#include <meta/display.h>
|
||||
|
||||
gboolean meta_sync_ring_init (MetaDisplay *dpy);
|
||||
void meta_sync_ring_destroy (void);
|
||||
gboolean meta_sync_ring_after_frame (void);
|
||||
gboolean meta_sync_ring_insert_wait (void);
|
||||
void meta_sync_ring_handle_event (XSyncAlarmNotifyEvent *event);
|
||||
|
||||
#endif /* _META_SYNC_RING_H_ */
|
||||
@@ -29,6 +29,9 @@
|
||||
#include <meta/errors.h>
|
||||
#include "util-private.h"
|
||||
|
||||
#include "x11/window-x11.h"
|
||||
#include "x11/window-x11-private.h"
|
||||
|
||||
/* Looks up the MetaWindow representing the frame of the given X window.
|
||||
* Used as a helper function by a bunch of the functions below.
|
||||
*
|
||||
@@ -69,6 +72,8 @@ meta_core_get (Display *xdisplay,
|
||||
|
||||
MetaDisplay *display = meta_display_for_x_display (xdisplay);
|
||||
MetaWindow *window = meta_display_lookup_x_window (display, xwindow);
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = window_x11->priv;
|
||||
|
||||
va_start (args, xwindow);
|
||||
|
||||
@@ -103,10 +108,10 @@ meta_core_get (Display *xdisplay,
|
||||
if (!*((gboolean*)answer)) goto out; /* see above */
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_WIDTH:
|
||||
*((gint*)answer) = window->rect.width;
|
||||
*((gint*)answer) = priv->client_rect.width;
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_HEIGHT:
|
||||
*((gint*)answer) = window->rect.height;
|
||||
*((gint*)answer) = priv->client_rect.height;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_FLAGS:
|
||||
*((MetaFrameFlags*)answer) = meta_frame_get_flags (window->frame);
|
||||
@@ -120,11 +125,8 @@ meta_core_get (Display *xdisplay,
|
||||
case META_CORE_GET_ICON:
|
||||
*((GdkPixbuf**)answer) = window->icon;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_WIDTH:
|
||||
*((gint*)answer) = window->frame->rect.width;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_HEIGHT:
|
||||
*((gint*)answer) = window->frame->rect.height;
|
||||
case META_CORE_GET_FRAME_RECT:
|
||||
meta_window_get_frame_rect (window, ((MetaRectangle*)answer));
|
||||
break;
|
||||
case META_CORE_GET_THEME_VARIANT:
|
||||
*((char**)answer) = window->gtk_theme_variant;
|
||||
|
||||
@@ -37,8 +37,7 @@ typedef enum
|
||||
META_CORE_GET_FRAME_TYPE,
|
||||
META_CORE_GET_MINI_ICON,
|
||||
META_CORE_GET_ICON,
|
||||
META_CORE_GET_FRAME_WIDTH,
|
||||
META_CORE_GET_FRAME_HEIGHT,
|
||||
META_CORE_GET_FRAME_RECT,
|
||||
META_CORE_GET_THEME_VARIANT,
|
||||
} MetaCoreGetType;
|
||||
|
||||
|
||||
@@ -1826,8 +1826,8 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
"Grab op %u on window %s successful\n",
|
||||
display->grab_op, window ? window->desc : "(null)");
|
||||
|
||||
meta_window_get_client_root_coords (display->grab_window,
|
||||
&display->grab_initial_window_pos);
|
||||
meta_window_get_frame_rect (display->grab_window,
|
||||
&display->grab_initial_window_pos);
|
||||
display->grab_anchor_window_pos = display->grab_initial_window_pos;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
@@ -2526,7 +2526,7 @@ mru_cmp (gconstpointer a,
|
||||
* @display: a #MetaDisplay
|
||||
* @type: type of tab list
|
||||
* @screen: a #MetaScreen
|
||||
* @workspace: (allow-none): origin workspace
|
||||
* @workspace: (nullable): origin workspace
|
||||
*
|
||||
* Determine the list of windows that should be displayed for Alt-TAB
|
||||
* functionality. The windows are returned in most recently used order.
|
||||
@@ -2595,7 +2595,7 @@ meta_display_get_tab_list (MetaDisplay *display,
|
||||
* @display: a #MetaDisplay
|
||||
* @type: type of tab list
|
||||
* @workspace: origin workspace
|
||||
* @window: (allow-none): starting window
|
||||
* @window: (nullable): starting window
|
||||
* @backward: If %TRUE, look for the previous window.
|
||||
*
|
||||
* Determine the next window that should be displayed for Alt-TAB
|
||||
@@ -3120,6 +3120,12 @@ meta_display_has_shape (MetaDisplay *display)
|
||||
return META_DISPLAY_HAS_SHAPE (display);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_has_sync (MetaDisplay *display)
|
||||
{
|
||||
return META_DISPLAY_HAS_XSYNC (display);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_get_focus_window:
|
||||
* @display: a #MetaDisplay
|
||||
@@ -3148,6 +3154,12 @@ meta_display_get_shape_event_base (MetaDisplay *display)
|
||||
return display->shape_event_base;
|
||||
}
|
||||
|
||||
int
|
||||
meta_display_get_sync_event_base (MetaDisplay *display)
|
||||
{
|
||||
return display->xsync_event_base;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_clear_mouse_mode:
|
||||
* @display: a #MetaDisplay
|
||||
|
||||
@@ -1134,13 +1134,8 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
initialize_grab_edge_resistance_data (display);
|
||||
}
|
||||
|
||||
/* Note that old_[xy] and new_[xy] are with respect to inner positions of
|
||||
* the window.
|
||||
*/
|
||||
void
|
||||
meta_window_edge_resistance_for_move (MetaWindow *window,
|
||||
int old_x,
|
||||
int old_y,
|
||||
int *new_x,
|
||||
int *new_y,
|
||||
GSourceFunc timeout_func,
|
||||
@@ -1153,8 +1148,8 @@ meta_window_edge_resistance_for_move (MetaWindow *window,
|
||||
meta_window_get_frame_rect (window, &old_outer);
|
||||
|
||||
proposed_outer = old_outer;
|
||||
proposed_outer.x += (*new_x - old_x);
|
||||
proposed_outer.y += (*new_y - old_y);
|
||||
proposed_outer.x = *new_x;
|
||||
proposed_outer.y = *new_y;
|
||||
new_outer = proposed_outer;
|
||||
|
||||
window->display->grab_last_user_action_was_snap = snap;
|
||||
@@ -1205,26 +1200,20 @@ meta_window_edge_resistance_for_move (MetaWindow *window,
|
||||
else
|
||||
smaller_y_change = bottom_change;
|
||||
|
||||
*new_x = old_x + smaller_x_change +
|
||||
*new_x = old_outer.x + smaller_x_change +
|
||||
(BOX_LEFT (*reference) - BOX_LEFT (old_outer));
|
||||
*new_y = old_y + smaller_y_change +
|
||||
*new_y = old_outer.y + smaller_y_change +
|
||||
(BOX_TOP (*reference) - BOX_TOP (old_outer));
|
||||
|
||||
meta_topic (META_DEBUG_EDGE_RESISTANCE,
|
||||
"outer x & y move-to coordinate changed from %d,%d to %d,%d\n",
|
||||
proposed_outer.x, proposed_outer.y,
|
||||
old_outer.x + (*new_x - old_x),
|
||||
old_outer.y + (*new_y - old_y));
|
||||
*new_x, *new_y);
|
||||
}
|
||||
}
|
||||
|
||||
/* Note that old_(width|height) and new_(width|height) are with respect to
|
||||
* sizes of the inner window.
|
||||
*/
|
||||
void
|
||||
meta_window_edge_resistance_for_resize (MetaWindow *window,
|
||||
int old_width,
|
||||
int old_height,
|
||||
int *new_width,
|
||||
int *new_height,
|
||||
int gravity,
|
||||
@@ -1237,8 +1226,8 @@ meta_window_edge_resistance_for_resize (MetaWindow *window,
|
||||
gboolean is_resize;
|
||||
|
||||
meta_window_get_frame_rect (window, &old_outer);
|
||||
proposed_outer_width = old_outer.width + (*new_width - old_width);
|
||||
proposed_outer_height = old_outer.height + (*new_height - old_height);
|
||||
proposed_outer_width = *new_width;
|
||||
proposed_outer_height = *new_height;
|
||||
meta_rectangle_resize_with_gravity (&old_outer,
|
||||
&new_outer,
|
||||
gravity,
|
||||
@@ -1256,8 +1245,8 @@ meta_window_edge_resistance_for_resize (MetaWindow *window,
|
||||
is_keyboard_op,
|
||||
is_resize))
|
||||
{
|
||||
*new_width = old_width + (new_outer.width - old_outer.width);
|
||||
*new_height = old_height + (new_outer.height - old_outer.height);
|
||||
*new_width = new_outer.width;
|
||||
*new_height = new_outer.height;
|
||||
|
||||
meta_topic (META_DEBUG_EDGE_RESISTANCE,
|
||||
"outer width & height got changed from %d,%d to %d,%d\n",
|
||||
|
||||
@@ -25,16 +25,12 @@
|
||||
#include "window-private.h"
|
||||
|
||||
void meta_window_edge_resistance_for_move (MetaWindow *window,
|
||||
int old_x,
|
||||
int old_y,
|
||||
int *new_x,
|
||||
int *new_y,
|
||||
GSourceFunc timeout_func,
|
||||
gboolean snap,
|
||||
gboolean is_keyboard_op);
|
||||
void meta_window_edge_resistance_for_resize (MetaWindow *window,
|
||||
int old_width,
|
||||
int old_height,
|
||||
int *new_width,
|
||||
int *new_height,
|
||||
int gravity,
|
||||
|
||||
@@ -33,9 +33,13 @@
|
||||
#include "bell.h"
|
||||
#include "workspace-private.h"
|
||||
#include "backends/meta-backend.h"
|
||||
#include "backends/native/meta-idle-monitor-native.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/native/meta-idle-monitor-native.h"
|
||||
#endif
|
||||
|
||||
#include "x11/window-x11.h"
|
||||
#include "x11/xprops.h"
|
||||
#include "wayland/meta-xwayland.h"
|
||||
@@ -1827,35 +1831,37 @@ meta_display_handle_xevent (MetaDisplay *display,
|
||||
static void
|
||||
handle_idletime_for_event (const ClutterEvent *event)
|
||||
{
|
||||
ClutterInputDevice *device, *source_device;
|
||||
MetaIdleMonitor *core_monitor, *device_monitor;
|
||||
int device_id;
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
/* This is handled by XSync under X11. */
|
||||
#if defined(CLUTTER_WINDOWING_X11)
|
||||
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
|
||||
return;
|
||||
#endif
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
device = clutter_event_get_device (event);
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
|
||||
core_monitor = meta_idle_monitor_get_core ();
|
||||
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
||||
|
||||
meta_idle_monitor_native_reset_idletime (core_monitor);
|
||||
meta_idle_monitor_native_reset_idletime (device_monitor);
|
||||
|
||||
source_device = clutter_event_get_source_device (event);
|
||||
if (source_device != device)
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
{
|
||||
ClutterInputDevice *device, *source_device;
|
||||
MetaIdleMonitor *core_monitor, *device_monitor;
|
||||
int device_id;
|
||||
|
||||
device = clutter_event_get_device (event);
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
|
||||
core_monitor = meta_idle_monitor_get_core ();
|
||||
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
||||
|
||||
meta_idle_monitor_native_reset_idletime (core_monitor);
|
||||
meta_idle_monitor_native_reset_idletime (device_monitor);
|
||||
|
||||
source_device = clutter_event_get_source_device (event);
|
||||
if (source_device != device)
|
||||
{
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
||||
meta_idle_monitor_native_reset_idletime (device_monitor);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_NATIVE_BACKEND */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -121,9 +121,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
"Incrementing unmaps_pending on %s for reparent\n", window->desc);
|
||||
window->unmaps_pending += 1;
|
||||
}
|
||||
/* window was reparented to this position */
|
||||
window->rect.x = 0;
|
||||
window->rect.y = 0;
|
||||
|
||||
stack_window.x11.xwindow = window->xwindow;
|
||||
meta_stack_tracker_record_remove (window->screen->stack_tracker,
|
||||
@@ -132,8 +129,8 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
XReparentWindow (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
frame->xwindow,
|
||||
window->rect.x,
|
||||
window->rect.y);
|
||||
frame->child_x,
|
||||
frame->child_y);
|
||||
/* FIXME handle this error */
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
@@ -202,7 +199,7 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
XReparentWindow (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
window->screen->xroot,
|
||||
/* Using anything other than meta_window_get_position()
|
||||
/* Using anything other than client root window coordinates
|
||||
* coordinates here means we'll need to ensure a configure
|
||||
* notify event is sent; see bug 399552.
|
||||
*/
|
||||
|
||||
@@ -57,7 +57,10 @@
|
||||
|
||||
#include "wayland/meta-wayland.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#endif
|
||||
|
||||
#define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings"
|
||||
#define SCHEMA_MUTTER_KEYBINDINGS "org.gnome.mutter.keybindings"
|
||||
@@ -1906,12 +1909,12 @@ process_mouse_move_resize_grab (MetaDisplay *display,
|
||||
else if (window->tile_mode != META_TILE_NONE)
|
||||
meta_window_tile (window);
|
||||
else
|
||||
meta_window_move_resize (display->grab_window,
|
||||
TRUE,
|
||||
display->grab_initial_window_pos.x,
|
||||
display->grab_initial_window_pos.y,
|
||||
display->grab_initial_window_pos.width,
|
||||
display->grab_initial_window_pos.height);
|
||||
meta_window_move_resize_frame (display->grab_window,
|
||||
TRUE,
|
||||
display->grab_initial_window_pos.x,
|
||||
display->grab_initial_window_pos.y,
|
||||
display->grab_initial_window_pos.width,
|
||||
display->grab_initial_window_pos.height);
|
||||
|
||||
/* End grab */
|
||||
return FALSE;
|
||||
@@ -1927,6 +1930,7 @@ process_keyboard_move_grab (MetaDisplay *display,
|
||||
ClutterKeyEvent *event)
|
||||
{
|
||||
gboolean handled;
|
||||
MetaRectangle frame_rect;
|
||||
int x, y;
|
||||
int incr;
|
||||
gboolean smart_snap;
|
||||
@@ -1941,7 +1945,9 @@ process_keyboard_move_grab (MetaDisplay *display,
|
||||
if (is_modifier (event->keyval))
|
||||
return TRUE;
|
||||
|
||||
meta_window_get_position (window, &x, &y);
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
x = frame_rect.x;
|
||||
y = frame_rect.y;
|
||||
|
||||
smart_snap = (event->modifier_state & CLUTTER_SHIFT_MASK) != 0;
|
||||
|
||||
@@ -1965,12 +1971,12 @@ process_keyboard_move_grab (MetaDisplay *display,
|
||||
if (window->shaken_loose)
|
||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||
else
|
||||
meta_window_move_resize (display->grab_window,
|
||||
TRUE,
|
||||
display->grab_initial_window_pos.x,
|
||||
display->grab_initial_window_pos.y,
|
||||
display->grab_initial_window_pos.width,
|
||||
display->grab_initial_window_pos.height);
|
||||
meta_window_move_resize_frame (display->grab_window,
|
||||
TRUE,
|
||||
display->grab_initial_window_pos.x,
|
||||
display->grab_initial_window_pos.y,
|
||||
display->grab_initial_window_pos.width,
|
||||
display->grab_initial_window_pos.height);
|
||||
}
|
||||
|
||||
/* When moving by increments, we still snap to edges if the move
|
||||
@@ -2016,23 +2022,18 @@ process_keyboard_move_grab (MetaDisplay *display,
|
||||
|
||||
if (handled)
|
||||
{
|
||||
MetaRectangle old_rect;
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Computed new window location %d,%d due to keypress\n",
|
||||
x, y);
|
||||
|
||||
meta_window_get_client_root_coords (window, &old_rect);
|
||||
|
||||
meta_window_edge_resistance_for_move (window,
|
||||
old_rect.x,
|
||||
old_rect.y,
|
||||
&x,
|
||||
&y,
|
||||
NULL,
|
||||
smart_snap,
|
||||
TRUE);
|
||||
|
||||
meta_window_move (window, TRUE, x, y);
|
||||
meta_window_move_frame (window, TRUE, x, y);
|
||||
meta_window_update_keyboard_move (window);
|
||||
}
|
||||
|
||||
@@ -2166,6 +2167,7 @@ process_keyboard_resize_grab (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
ClutterKeyEvent *event)
|
||||
{
|
||||
MetaRectangle frame_rect;
|
||||
gboolean handled;
|
||||
int height_inc;
|
||||
int width_inc;
|
||||
@@ -2186,12 +2188,12 @@ process_keyboard_resize_grab (MetaDisplay *display,
|
||||
if (event->keyval == CLUTTER_KEY_Escape)
|
||||
{
|
||||
/* End resize and restore to original state. */
|
||||
meta_window_move_resize (display->grab_window,
|
||||
TRUE,
|
||||
display->grab_initial_window_pos.x,
|
||||
display->grab_initial_window_pos.y,
|
||||
display->grab_initial_window_pos.width,
|
||||
display->grab_initial_window_pos.height);
|
||||
meta_window_move_resize_frame (display->grab_window,
|
||||
TRUE,
|
||||
display->grab_initial_window_pos.x,
|
||||
display->grab_initial_window_pos.y,
|
||||
display->grab_initial_window_pos.width,
|
||||
display->grab_initial_window_pos.height);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2202,6 +2204,10 @@ process_keyboard_resize_grab (MetaDisplay *display,
|
||||
width = window->rect.width;
|
||||
height = window->rect.height;
|
||||
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
width = frame_rect.width;
|
||||
height = frame_rect.height;
|
||||
|
||||
gravity = meta_resize_gravity_from_grab_op (display->grab_op);
|
||||
|
||||
smart_snap = (event->modifier_state & CLUTTER_SHIFT_MASK) != 0;
|
||||
@@ -2359,18 +2365,13 @@ process_keyboard_resize_grab (MetaDisplay *display,
|
||||
|
||||
if (handled)
|
||||
{
|
||||
MetaRectangle old_rect;
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Computed new window size due to keypress: "
|
||||
"%dx%d, gravity %s\n",
|
||||
width, height, meta_gravity_to_string (gravity));
|
||||
|
||||
old_rect = window->rect; /* Don't actually care about x,y */
|
||||
|
||||
/* Do any edge resistance/snapping */
|
||||
meta_window_edge_resistance_for_resize (window,
|
||||
old_rect.width,
|
||||
old_rect.height,
|
||||
&width,
|
||||
&height,
|
||||
gravity,
|
||||
@@ -2378,15 +2379,11 @@ process_keyboard_resize_grab (MetaDisplay *display,
|
||||
smart_snap,
|
||||
TRUE);
|
||||
|
||||
/* We don't need to update unless the specified width and height
|
||||
* are actually different from what we had before.
|
||||
*/
|
||||
if (window->rect.width != width || window->rect.height != height)
|
||||
meta_window_resize_with_gravity (window,
|
||||
TRUE,
|
||||
width,
|
||||
height,
|
||||
gravity);
|
||||
meta_window_resize_frame_with_gravity (window,
|
||||
TRUE,
|
||||
width,
|
||||
height,
|
||||
gravity);
|
||||
|
||||
meta_window_update_keyboard_resize (window, FALSE);
|
||||
}
|
||||
@@ -3172,6 +3169,7 @@ handle_set_spew_mark (MetaDisplay *display,
|
||||
meta_verbose ("-- MARK MARK MARK MARK --\n");
|
||||
}
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static void
|
||||
handle_switch_vt (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
@@ -3189,11 +3187,12 @@ handle_switch_vt (MetaDisplay *display,
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_NATIVE_BACKEND */
|
||||
|
||||
/**
|
||||
* meta_keybindings_set_custom_handler:
|
||||
* @name: The name of the keybinding to set
|
||||
* @handler: (allow-none): The new handler function
|
||||
* @handler: (nullable): The new handler function
|
||||
* @user_data: User data to pass to the callback
|
||||
* @free_data: Will be called when this handler is overridden.
|
||||
*
|
||||
@@ -3481,7 +3480,9 @@ init_builtin_key_bindings (MetaDisplay *display)
|
||||
META_KEYBINDING_ACTION_SET_SPEW_MARK,
|
||||
handle_set_spew_mark, 0);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
{
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-1",
|
||||
@@ -3532,6 +3533,7 @@ init_builtin_key_bindings (MetaDisplay *display)
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 7);
|
||||
}
|
||||
#endif /* HAVE_NATIVE_BACKEND */
|
||||
|
||||
#undef REVERSES_AND_REVERSED
|
||||
|
||||
|
||||
@@ -181,7 +181,9 @@ static gboolean opt_replace_wm;
|
||||
static gboolean opt_disable_sm;
|
||||
static gboolean opt_sync;
|
||||
static gboolean opt_wayland;
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static gboolean opt_display_server;
|
||||
#endif
|
||||
|
||||
static GOptionEntry meta_options[] = {
|
||||
{
|
||||
@@ -225,11 +227,13 @@ static GOptionEntry meta_options[] = {
|
||||
N_("Run as a wayland compositor"),
|
||||
NULL
|
||||
},
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
{
|
||||
"display-server", 0, 0, G_OPTION_ARG_NONE,
|
||||
&opt_display_server,
|
||||
N_("Run as a full display server, rather than nested")
|
||||
},
|
||||
#endif
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -332,8 +336,10 @@ meta_init (void)
|
||||
if (g_getenv ("MUTTER_DEBUG"))
|
||||
meta_set_debugging (TRUE);
|
||||
|
||||
#if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND)
|
||||
if (opt_display_server)
|
||||
clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL);
|
||||
#endif
|
||||
|
||||
meta_set_is_wayland_compositor (opt_wayland);
|
||||
|
||||
|
||||
113
src/core/place.c
113
src/core/place.c
@@ -515,85 +515,84 @@ find_first_fit (MetaWindow *window,
|
||||
meta_window_get_frame_rect (window, &rect);
|
||||
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
{
|
||||
char monitor_location_string[RECT_LENGTH];
|
||||
meta_rectangle_to_string (&window->screen->monitor_infos[monitor].rect,
|
||||
monitor_location_string);
|
||||
meta_topic (META_DEBUG_XINERAMA,
|
||||
"Natural monitor is %s\n",
|
||||
monitor_location_string);
|
||||
}
|
||||
{
|
||||
char monitor_location_string[RECT_LENGTH];
|
||||
meta_rectangle_to_string (&window->screen->monitor_infos[monitor].rect,
|
||||
monitor_location_string);
|
||||
meta_topic (META_DEBUG_XINERAMA,
|
||||
"Natural monitor is %s\n",
|
||||
monitor_location_string);
|
||||
}
|
||||
#endif
|
||||
|
||||
meta_window_get_work_area_for_monitor (window, monitor, &work_area);
|
||||
meta_window_get_work_area_for_monitor (window, monitor, &work_area);
|
||||
|
||||
center_tile_rect_in_area (&rect, &work_area);
|
||||
center_tile_rect_in_area (&rect, &work_area);
|
||||
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, windows))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, windows))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
|
||||
retval = TRUE;
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* try below each window */
|
||||
tmp = below_sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle frame_rect;
|
||||
/* try below each window */
|
||||
tmp = below_sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle frame_rect;
|
||||
|
||||
meta_window_get_frame_rect (w, &frame_rect);
|
||||
meta_window_get_frame_rect (w, &frame_rect);
|
||||
|
||||
rect.x = frame_rect.x;
|
||||
rect.y = frame_rect.y + frame_rect.height;
|
||||
rect.x = frame_rect.x;
|
||||
rect.y = frame_rect.y + frame_rect.height;
|
||||
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, below_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, below_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
|
||||
retval = TRUE;
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
/* try to the right of each window */
|
||||
tmp = right_sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle frame_rect;
|
||||
/* try to the right of each window */
|
||||
tmp = right_sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle frame_rect;
|
||||
|
||||
meta_window_get_frame_rect (w, &frame_rect);
|
||||
meta_window_get_frame_rect (w, &frame_rect);
|
||||
|
||||
rect.x = frame_rect.x + frame_rect.width;
|
||||
rect.y = frame_rect.y;
|
||||
rect.x = frame_rect.x + frame_rect.width;
|
||||
rect.y = frame_rect.y;
|
||||
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, right_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, right_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
|
||||
retval = TRUE;
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
g_list_free (below_sorted);
|
||||
g_list_free (right_sorted);
|
||||
return retval;
|
||||
|
||||
@@ -180,7 +180,7 @@ typedef struct
|
||||
|
||||
/**
|
||||
* MetaStringPreference:
|
||||
* @handler: (allow-none): A handler. Many of the string preferences
|
||||
* @handler: (nullable): A handler. Many of the string preferences
|
||||
* aren't stored as strings and need parsing; others of them have
|
||||
* default values which can't be solved in the general case. If you
|
||||
* include a function pointer here, it will be called instead of writing
|
||||
@@ -192,7 +192,7 @@ typedef struct
|
||||
* in particular the @result (out) parameter as returned by
|
||||
* g_settings_get_mapped() will be ignored in all cases.
|
||||
* This may be %NULL. If it is, see "target", below.
|
||||
* @target: (allow-none): Where to write the incoming string.
|
||||
* @target: (nullable): Where to write the incoming string.
|
||||
* This must be %NULL if the handler is non-%NULL.
|
||||
* If the incoming string is %NULL, no change will be made.
|
||||
*/
|
||||
|
||||
@@ -357,7 +357,8 @@ struct _MetaWindow
|
||||
/* if non-NULL, the bounds of the window frame */
|
||||
cairo_region_t *frame_bounds;
|
||||
|
||||
/* if non-NULL, the bounding shape region of the window */
|
||||
/* if non-NULL, the bounding shape region of the window. Relative to
|
||||
* the server-side client window. */
|
||||
cairo_region_t *shape_region;
|
||||
|
||||
/* if non-NULL, the opaque region _NET_WM_OPAQUE_REGION */
|
||||
@@ -403,32 +404,23 @@ struct _MetaWindow
|
||||
gboolean has_custom_frame_extents;
|
||||
GtkBorder custom_frame_extents;
|
||||
|
||||
/* The size we set the window to last (i.e. what we believe
|
||||
* to be its actual size on the server). The x, y are
|
||||
* the actual server-side x,y so are relative to the frame
|
||||
* (meaning that they just hold the frame width and height)
|
||||
* or the root window (meaning they specify the location
|
||||
* of the top left of the inner window) as appropriate.
|
||||
*/
|
||||
/* The rectangles here are in "frame rect" coordinates. See the
|
||||
* comment at the top of meta_window_move_resize_internal() for more
|
||||
* information. */
|
||||
|
||||
/* The current window geometry of the window. */
|
||||
MetaRectangle rect;
|
||||
|
||||
/* The geometry to restore when we unmaximize. The position is in
|
||||
* root window coords, even if there's a frame, which contrasts with
|
||||
* window->rect above. Note that this gives the position and size
|
||||
* of the client window (i.e. ignoring the frame).
|
||||
*/
|
||||
/* The geometry to restore when we unmaximize. */
|
||||
MetaRectangle saved_rect;
|
||||
|
||||
/* This is the geometry the window will have if no constraints have
|
||||
* applied. We use this whenever we are moving implicitly (for example,
|
||||
* if we move to avoid a panel, we can snap back to this position if
|
||||
* the panel moves again). Note that this gives the position and size
|
||||
* of the client window (i.e. ignoring the frame).
|
||||
*
|
||||
* Position always in root coords, unlike window->rect.
|
||||
* the panel moves again).
|
||||
*/
|
||||
MetaRectangle unconstrained_rect;
|
||||
|
||||
|
||||
/* Cached net_wm_icon_geometry */
|
||||
MetaRectangle icon_geometry;
|
||||
|
||||
@@ -539,23 +531,12 @@ void meta_window_update_fullscreen_monitors (MetaWindow *window,
|
||||
unsigned long left,
|
||||
unsigned long right);
|
||||
|
||||
void meta_window_resize_frame_with_gravity (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int w,
|
||||
int h,
|
||||
int gravity);
|
||||
|
||||
/* args to move are window pos, not frame pos */
|
||||
void meta_window_move (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int root_x_nw,
|
||||
int root_y_nw);
|
||||
void meta_window_move_resize (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int root_x_nw,
|
||||
int root_y_nw,
|
||||
int w,
|
||||
int h);
|
||||
void meta_window_resize_with_gravity (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int w,
|
||||
int h,
|
||||
int gravity);
|
||||
void meta_window_change_workspace (MetaWindow *window,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
@@ -564,17 +545,6 @@ gboolean meta_window_should_be_showing (MetaWindow *window);
|
||||
|
||||
void meta_window_update_struts (MetaWindow *window);
|
||||
|
||||
/* this gets root coords */
|
||||
void meta_window_get_position (MetaWindow *window,
|
||||
int *x,
|
||||
int *y);
|
||||
|
||||
/* Gets root coords for x, y, width & height of client window; uses
|
||||
* meta_window_get_position for x & y.
|
||||
*/
|
||||
void meta_window_get_client_root_coords (MetaWindow *window,
|
||||
MetaRectangle *rect);
|
||||
|
||||
/* gets position we need to set to stay in current position,
|
||||
* assuming position will be gravity-compensated. i.e.
|
||||
* this is the position a client would send in a configure
|
||||
@@ -721,7 +691,7 @@ void meta_window_update_resize (MetaWindow *window,
|
||||
void meta_window_move_resize_internal (MetaWindow *window,
|
||||
MetaMoveResizeFlags flags,
|
||||
int gravity,
|
||||
MetaRectangle client_rect);
|
||||
MetaRectangle frame_rect);
|
||||
|
||||
void meta_window_grab_op_began (MetaWindow *window, MetaGrabOp op);
|
||||
void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op);
|
||||
|
||||
@@ -1044,9 +1044,6 @@ _meta_window_shared_new (MetaDisplay *display,
|
||||
if (window->attached)
|
||||
meta_window_recalc_features (window);
|
||||
|
||||
if (window->decorated)
|
||||
meta_window_ensure_frame (window);
|
||||
|
||||
if (window->type == META_WINDOW_DESKTOP ||
|
||||
window->type == META_WINDOW_DOCK)
|
||||
{
|
||||
@@ -1393,9 +1390,6 @@ meta_window_unmanage (MetaWindow *window,
|
||||
|
||||
META_WINDOW_GET_CLASS (window)->unmanage (window);
|
||||
|
||||
if (window->frame)
|
||||
meta_window_destroy_frame (window);
|
||||
|
||||
meta_prefs_remove_listener (prefs_changed_callback, window);
|
||||
meta_screen_queue_check_fullscreen (window->screen);
|
||||
|
||||
@@ -2654,15 +2648,11 @@ meta_window_save_rect (MetaWindow *window)
|
||||
{
|
||||
window->saved_rect.x = window->rect.x;
|
||||
window->saved_rect.width = window->rect.width;
|
||||
if (window->frame)
|
||||
window->saved_rect.x += window->frame->rect.x;
|
||||
}
|
||||
if (!window->maximized_vertically)
|
||||
{
|
||||
window->saved_rect.y = window->rect.y;
|
||||
window->saved_rect.height = window->rect.height;
|
||||
if (window->frame)
|
||||
window->saved_rect.y += window->frame->rect.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3016,12 +3006,12 @@ unmaximize_window_before_freeing (MetaWindow *window)
|
||||
* Moreover, it will need to know the unmaximized geometry,
|
||||
* therefore move_resize the window to saved_rect here
|
||||
* before closing it. */
|
||||
meta_window_move_resize (window,
|
||||
FALSE,
|
||||
window->saved_rect.x,
|
||||
window->saved_rect.y,
|
||||
window->saved_rect.width,
|
||||
window->saved_rect.height);
|
||||
meta_window_move_resize_frame (window,
|
||||
FALSE,
|
||||
window->saved_rect.x,
|
||||
window->saved_rect.y,
|
||||
window->saved_rect.width,
|
||||
window->saved_rect.height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3078,7 +3068,7 @@ meta_window_unmaximize_internal (MetaWindow *window,
|
||||
/* Unmaximize to the saved_rect position in the direction(s)
|
||||
* being unmaximized.
|
||||
*/
|
||||
meta_window_get_client_root_coords (window, &target_rect);
|
||||
target_rect = old_rect;
|
||||
|
||||
/* Avoid unmaximizing to "almost maximized" size when the previous size
|
||||
* is greater then 80% of the work area use MAX_UNMAXIMIZED_WINDOW_AREA of the work area as upper limit
|
||||
@@ -3115,7 +3105,9 @@ meta_window_unmaximize_internal (MetaWindow *window,
|
||||
/* Window's size hints may have changed while maximized, making
|
||||
* saved_rect invalid. #329152
|
||||
*/
|
||||
meta_window_frame_rect_to_client_rect (window, &target_rect, &target_rect);
|
||||
ensure_size_hints_satisfied (&target_rect, &window->size_hints);
|
||||
meta_window_client_rect_to_frame_rect (window, &target_rect, &target_rect);
|
||||
|
||||
meta_window_move_resize_internal (window,
|
||||
META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION,
|
||||
@@ -3176,7 +3168,6 @@ meta_window_unmaximize_with_gravity (MetaWindow *window,
|
||||
{
|
||||
MetaRectangle desired_rect;
|
||||
|
||||
meta_window_get_position (window, &desired_rect.x, &desired_rect.y);
|
||||
desired_rect.width = new_width;
|
||||
desired_rect.height = new_height;
|
||||
|
||||
@@ -3293,12 +3284,12 @@ meta_window_unmake_fullscreen (MetaWindow *window)
|
||||
meta_window_recalc_features (window);
|
||||
set_net_wm_state (window);
|
||||
|
||||
meta_window_move_resize (window,
|
||||
FALSE,
|
||||
target_rect.x,
|
||||
target_rect.y,
|
||||
target_rect.width,
|
||||
target_rect.height);
|
||||
meta_window_move_resize_frame (window,
|
||||
FALSE,
|
||||
target_rect.x,
|
||||
target_rect.y,
|
||||
target_rect.width,
|
||||
target_rect.height);
|
||||
|
||||
meta_window_update_layer (window);
|
||||
|
||||
@@ -3532,7 +3523,7 @@ maybe_move_attached_dialog (MetaWindow *window,
|
||||
{
|
||||
if (meta_window_is_attached_dialog (window))
|
||||
/* It ignores x,y for such a dialog */
|
||||
meta_window_move (window, FALSE, 0, 0);
|
||||
meta_window_move_frame (window, FALSE, 0, 0);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -3645,13 +3636,27 @@ void
|
||||
meta_window_move_resize_internal (MetaWindow *window,
|
||||
MetaMoveResizeFlags flags,
|
||||
int gravity,
|
||||
MetaRectangle client_rect)
|
||||
MetaRectangle frame_rect)
|
||||
{
|
||||
/* The rectangle here that's passed in is always the root position
|
||||
* of the client window. For undecorated or client-decorated windows,
|
||||
* this is the root position of the X11 window. For server-decorated
|
||||
* windows, this is the root position of the client area of the window.
|
||||
/* The rectangle here that's passed in *always* in "frame rect"
|
||||
* coordinates. That means the position of the frame's visible bounds,
|
||||
* with x and y being absolute (root window) coordinates.
|
||||
*
|
||||
* For an X11 framed window, the client window's server rectangle is
|
||||
* inset from this rectangle by the frame's visible borders, and the
|
||||
* frame window's server rectangle is outset by the invisible borders.
|
||||
*
|
||||
* For an X11 unframed window, the rectangle here directly matches
|
||||
* the server's rectangle, since the visible and invisible borders
|
||||
* are both 0.
|
||||
*
|
||||
* For an X11 CSD window, the client window's server rectangle is
|
||||
* outset from this rectagle by the client-specified frame extents.
|
||||
*
|
||||
* For a Wayland window, this rectangle can simply be sent directly
|
||||
* to the client.
|
||||
*/
|
||||
|
||||
gboolean did_placement;
|
||||
MetaRectangle unconstrained_rect;
|
||||
MetaRectangle constrained_rect;
|
||||
@@ -3674,18 +3679,15 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
* resizing the old rectangle with the given gravity. */
|
||||
if ((flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION)) == META_IS_RESIZE_ACTION)
|
||||
{
|
||||
MetaRectangle old_rect;
|
||||
|
||||
meta_window_get_client_root_coords (window, &old_rect);
|
||||
meta_rectangle_resize_with_gravity (&old_rect,
|
||||
meta_rectangle_resize_with_gravity (&window->rect,
|
||||
&unconstrained_rect,
|
||||
gravity,
|
||||
client_rect.width,
|
||||
client_rect.height);
|
||||
frame_rect.width,
|
||||
frame_rect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
unconstrained_rect = client_rect;
|
||||
unconstrained_rect = frame_rect;
|
||||
}
|
||||
|
||||
/* If this is only a move, then ignore the passed in size and
|
||||
@@ -3706,15 +3708,21 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
MetaRectangle old_rect;
|
||||
meta_window_get_frame_rect (window, &old_rect);
|
||||
|
||||
meta_window_client_rect_to_frame_rect (window, &constrained_rect, &constrained_rect);
|
||||
|
||||
meta_window_constrain (window,
|
||||
flags,
|
||||
gravity,
|
||||
&old_rect,
|
||||
&constrained_rect);
|
||||
}
|
||||
|
||||
meta_window_frame_rect_to_client_rect (window, &constrained_rect, &constrained_rect);
|
||||
/* If we did placement, then we need to save the position that the window
|
||||
* was placed at to make sure that meta_window_move_resize_now places the
|
||||
* window correctly.
|
||||
*/
|
||||
if (did_placement)
|
||||
{
|
||||
window->unconstrained_rect.x = constrained_rect.x;
|
||||
window->unconstrained_rect.y = constrained_rect.y;
|
||||
}
|
||||
|
||||
/* Do the protocol-specific move/resize logic */
|
||||
@@ -3736,12 +3744,6 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
|
||||
meta_window_update_monitor (window);
|
||||
|
||||
/* Invariants leaving this function are:
|
||||
* a) window->rect and frame->rect reflect the actual
|
||||
* server-side size/pos of window->xwindow and frame->xwindow
|
||||
* b) all constraints are obeyed by window->rect and frame->rect
|
||||
*/
|
||||
|
||||
if ((result & META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED) && window->frame_bounds)
|
||||
{
|
||||
cairo_region_destroy (window->frame_bounds);
|
||||
@@ -3754,33 +3756,6 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
window->screen->active_workspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_move:
|
||||
* @window: a #MetaWindow
|
||||
* @user_op: bool to indicate whether or not this is a user operation
|
||||
* @root_x_nw: desired x pos
|
||||
* @root_y_nw: desired y pos
|
||||
*
|
||||
* Moves the window to the desired location on window's assigned workspace.
|
||||
* NOTE: does NOT place according to the origin of the enclosing
|
||||
* frame/window-decoration, but according to the origin of the window,
|
||||
* itself.
|
||||
*/
|
||||
void
|
||||
meta_window_move (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int root_x_nw,
|
||||
int root_y_nw)
|
||||
{
|
||||
MetaMoveResizeFlags flags;
|
||||
MetaRectangle rect = { root_x_nw, root_y_nw, 0, 0 };
|
||||
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_MOVE_ACTION;
|
||||
meta_window_move_resize_internal (window, flags, NorthWestGravity, rect);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_move_frame:
|
||||
* @window: a #MetaWindow
|
||||
@@ -3799,10 +3774,13 @@ meta_window_move_frame (MetaWindow *window,
|
||||
int root_x_nw,
|
||||
int root_y_nw)
|
||||
{
|
||||
MetaMoveResizeFlags flags;
|
||||
MetaRectangle rect = { root_x_nw, root_y_nw, 0, 0 };
|
||||
|
||||
meta_window_frame_rect_to_client_rect (window, &rect, &rect);
|
||||
meta_window_move (window, user_op, rect.x, rect.y);
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_MOVE_ACTION;
|
||||
meta_window_move_resize_internal (window, flags, NorthWestGravity, rect);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3846,10 +3824,14 @@ meta_window_move_resize_frame (MetaWindow *window,
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
MetaMoveResizeFlags flags;
|
||||
MetaRectangle rect = { root_x_nw, root_y_nw, w, h };
|
||||
meta_window_frame_rect_to_client_rect (window, &rect, &rect);
|
||||
|
||||
meta_window_move_resize (window, user_op, rect.x, rect.y, rect.width, rect.height);
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||
|
||||
meta_window_move_resize_internal (window, flags, NorthWestGravity, rect);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3886,35 +3868,11 @@ meta_window_move_to_monitor (MetaWindow *window,
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_move_resize (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int root_x_nw,
|
||||
int root_y_nw,
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
MetaMoveResizeFlags flags;
|
||||
MetaRectangle rect;
|
||||
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
flags = (user_op ? META_IS_USER_ACTION : 0) |
|
||||
META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||
|
||||
rect.x = root_x_nw;
|
||||
rect.y = root_y_nw;
|
||||
rect.width = w;
|
||||
rect.height = h;
|
||||
|
||||
meta_window_move_resize_internal (window, flags, NorthWestGravity, rect);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_resize_with_gravity (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int w,
|
||||
int h,
|
||||
int gravity)
|
||||
meta_window_resize_frame_with_gravity (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int w,
|
||||
int h,
|
||||
int gravity)
|
||||
{
|
||||
MetaMoveResizeFlags flags;
|
||||
MetaRectangle rect;
|
||||
@@ -3929,11 +3887,11 @@ meta_window_resize_with_gravity (MetaWindow *window,
|
||||
static void
|
||||
meta_window_move_resize_now (MetaWindow *window)
|
||||
{
|
||||
meta_window_move_resize (window, FALSE,
|
||||
window->unconstrained_rect.x,
|
||||
window->unconstrained_rect.y,
|
||||
window->unconstrained_rect.width,
|
||||
window->unconstrained_rect.height);
|
||||
meta_window_move_resize_frame (window, FALSE,
|
||||
window->unconstrained_rect.x,
|
||||
window->unconstrained_rect.y,
|
||||
window->unconstrained_rect.width,
|
||||
window->unconstrained_rect.height);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -3976,36 +3934,6 @@ idle_move_resize (gpointer data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_get_position (MetaWindow *window,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
if (window->frame)
|
||||
{
|
||||
if (x)
|
||||
*x = window->frame->rect.x + window->frame->child_x;
|
||||
if (y)
|
||||
*y = window->frame->rect.y + window->frame->child_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x)
|
||||
*x = window->rect.x;
|
||||
if (y)
|
||||
*y = window->rect.y;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_get_client_root_coords (MetaWindow *window,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
meta_window_get_position (window, &rect->x, &rect->y);
|
||||
rect->width = window->rect.width;
|
||||
rect->height = window->rect.height;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_get_gravity_position (MetaWindow *window,
|
||||
int gravity,
|
||||
@@ -4124,7 +4052,10 @@ meta_window_get_input_rect (const MetaWindow *window,
|
||||
if (window->frame)
|
||||
*rect = window->frame->rect;
|
||||
else
|
||||
*rect = window->rect;
|
||||
{
|
||||
*rect = window->rect;
|
||||
meta_window_frame_rect_to_client_rect ((MetaWindow *) window, rect, rect);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4234,30 +4165,7 @@ void
|
||||
meta_window_get_frame_rect (const MetaWindow *window,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
if (window->frame)
|
||||
{
|
||||
MetaFrameBorders borders;
|
||||
*rect = window->frame->rect;
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
|
||||
rect->x += borders.invisible.left;
|
||||
rect->y += borders.invisible.top;
|
||||
rect->width -= borders.invisible.left + borders.invisible.right;
|
||||
rect->height -= borders.invisible.top + borders.invisible.bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
*rect = window->rect;
|
||||
|
||||
if (window->has_custom_frame_extents)
|
||||
{
|
||||
const GtkBorder *extents = &window->custom_frame_extents;
|
||||
rect->x += extents->left;
|
||||
rect->y += extents->top;
|
||||
rect->width -= extents->left + extents->right;
|
||||
rect->height -= extents->top + extents->bottom;
|
||||
}
|
||||
}
|
||||
*rect = window->rect;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4292,22 +4200,18 @@ void
|
||||
meta_window_get_client_area_rect (const MetaWindow *window,
|
||||
cairo_rectangle_int_t *rect)
|
||||
{
|
||||
if (window->frame)
|
||||
{
|
||||
rect->x = window->frame->child_x;
|
||||
rect->y = window->frame->child_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect->x = 0;
|
||||
rect->y = 0;
|
||||
}
|
||||
MetaFrameBorders borders;
|
||||
|
||||
rect->width = window->rect.width;
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
|
||||
rect->x = borders.total.left;
|
||||
rect->y = borders.total.top;
|
||||
|
||||
rect->width = window->rect.width - borders.visible.left - borders.visible.right;
|
||||
if (window->shaded)
|
||||
rect->height = 0;
|
||||
else
|
||||
rect->height = window->rect.height;
|
||||
rect->height = window->rect.height - borders.visible.top - borders.visible.bottom;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4895,7 +4799,7 @@ meta_window_get_icon_geometry (MetaWindow *window,
|
||||
/**
|
||||
* meta_window_set_icon_geometry:
|
||||
* @window: a #MetaWindow
|
||||
* @rect: (allow-none): rectangle with the desired geometry or %NULL.
|
||||
* @rect: (nullable): rectangle with the desired geometry or %NULL.
|
||||
*
|
||||
* Sets or unsets the location of the icon corresponding to the window. If
|
||||
* set, the location should correspond to a dock, task bar or other user
|
||||
@@ -5694,7 +5598,7 @@ update_move (MetaWindow *window,
|
||||
meta_screen_update_tile_preview (window->screen,
|
||||
window->tile_mode != META_TILE_NONE);
|
||||
|
||||
meta_window_get_client_root_coords (window, &old);
|
||||
meta_window_get_frame_rect (window, &old);
|
||||
|
||||
/* Don't allow movement in the maximized directions or while tiled */
|
||||
if (window->maximized_horizontally || META_WINDOW_TILED_SIDE_BY_SIDE (window))
|
||||
@@ -5704,15 +5608,13 @@ update_move (MetaWindow *window,
|
||||
|
||||
/* Do any edge resistance/snapping */
|
||||
meta_window_edge_resistance_for_move (window,
|
||||
old.x,
|
||||
old.y,
|
||||
&new_x,
|
||||
&new_y,
|
||||
update_move_timeout,
|
||||
snap,
|
||||
FALSE);
|
||||
|
||||
meta_window_move (window, TRUE, new_x, new_y);
|
||||
meta_window_move_frame (window, TRUE, new_x, new_y);
|
||||
}
|
||||
|
||||
/* When resizing a maximized window by using alt-middle-drag (resizing
|
||||
@@ -5998,7 +5900,7 @@ update_resize (MetaWindow *window,
|
||||
window->display->grab_resize_timeout_id = 0;
|
||||
}
|
||||
|
||||
old = window->rect; /* Don't actually care about x,y */
|
||||
meta_window_get_frame_rect (window, &old);
|
||||
|
||||
/* One sided resizing ought to actually be one-sided, despite the fact that
|
||||
* aspect ratio windows don't interact nicely with the above stuff. So,
|
||||
@@ -6026,8 +5928,6 @@ update_resize (MetaWindow *window,
|
||||
|
||||
/* Do any edge resistance/snapping */
|
||||
meta_window_edge_resistance_for_resize (window,
|
||||
old.width,
|
||||
old.height,
|
||||
&new_w,
|
||||
&new_h,
|
||||
gravity,
|
||||
@@ -6037,13 +5937,7 @@ update_resize (MetaWindow *window,
|
||||
|
||||
if (new_unmaximize == window->display->grab_resize_unmaximize)
|
||||
{
|
||||
/* We don't need to update unless the specified width and height
|
||||
* are actually different from what we had before.
|
||||
*/
|
||||
if (old.width != new_w || old.height != new_h)
|
||||
{
|
||||
meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
|
||||
}
|
||||
meta_window_resize_frame_with_gravity (window, TRUE, new_w, new_h, gravity);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6582,8 +6476,8 @@ warp_grab_pointer (MetaWindow *window,
|
||||
display->grab_anchor_root_y = *y;
|
||||
display->grab_latest_motion_x = *x;
|
||||
display->grab_latest_motion_y = *y;
|
||||
meta_window_get_client_root_coords (window,
|
||||
&display->grab_anchor_window_pos);
|
||||
meta_window_get_frame_rect (window,
|
||||
&display->grab_anchor_window_pos);
|
||||
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
@@ -7396,7 +7290,7 @@ meta_window_get_frame_type (MetaWindow *window)
|
||||
*
|
||||
* Gets a region representing the outer bounds of the window's frame.
|
||||
*
|
||||
* Return value: (transfer none) (allow-none): a #cairo_region_t
|
||||
* Return value: (transfer none) (nullable): a #cairo_region_t
|
||||
* holding the outer bounds of the window, or %NULL if the window
|
||||
* doesn't have a frame.
|
||||
*/
|
||||
@@ -7441,7 +7335,7 @@ meta_window_is_attached_dialog (MetaWindow *window)
|
||||
* - there is no 3rd window stacked between both tiled windows that's
|
||||
* partially visible in the common edge.
|
||||
*
|
||||
* Return value: (transfer none) (allow-none): the matching tiled window or
|
||||
* Return value: (transfer none) (nullable): the matching tiled window or
|
||||
* %NULL if it doesn't exist.
|
||||
*/
|
||||
MetaWindow *
|
||||
|
||||
@@ -75,6 +75,7 @@ Display *meta_display_get_xdisplay (MetaDisplay *display);
|
||||
MetaCompositor *meta_display_get_compositor (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_has_shape (MetaDisplay *display);
|
||||
gboolean meta_display_has_sync (MetaDisplay *display);
|
||||
|
||||
MetaWindow *meta_display_get_focus_window (MetaDisplay *display);
|
||||
|
||||
@@ -83,6 +84,7 @@ gboolean meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
|
||||
|
||||
int meta_display_get_damage_event_base (MetaDisplay *display);
|
||||
int meta_display_get_shape_event_base (MetaDisplay *display);
|
||||
int meta_display_get_sync_event_base (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_xserver_time_is_before (MetaDisplay *display,
|
||||
guint32 time1,
|
||||
|
||||
@@ -147,7 +147,6 @@ const char * meta_window_get_gtk_window_object_path (MetaWindow *window);
|
||||
const char * meta_window_get_gtk_app_menu_object_path (MetaWindow *window);
|
||||
const char * meta_window_get_gtk_menubar_object_path (MetaWindow *window);
|
||||
|
||||
void meta_window_move(MetaWindow *window, gboolean user_op, int root_x_nw, int root_y_nw);
|
||||
void meta_window_move_frame(MetaWindow *window, gboolean user_op, int root_x_nw, int root_y_nw);
|
||||
void meta_window_move_resize_frame (MetaWindow *window, gboolean user_op, int root_x_nw, int root_y_nw, int w, int h);
|
||||
void meta_window_move_to_monitor (MetaWindow *window, int monitor);
|
||||
|
||||
@@ -1601,21 +1601,20 @@ static void
|
||||
clip_region_to_visible_frame_border (cairo_region_t *region,
|
||||
MetaUIFrame *frame)
|
||||
{
|
||||
MetaRectangle frame_rect;
|
||||
cairo_rectangle_int_t area;
|
||||
cairo_region_t *frame_border;
|
||||
MetaFrameFlags flags;
|
||||
MetaFrameType type;
|
||||
MetaFrameBorders borders;
|
||||
Display *display;
|
||||
int frame_width, frame_height;
|
||||
|
||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
|
||||
meta_core_get (display, frame->xwindow,
|
||||
META_CORE_GET_FRAME_FLAGS, &flags,
|
||||
META_CORE_GET_FRAME_TYPE, &type,
|
||||
META_CORE_GET_FRAME_WIDTH, &frame_width,
|
||||
META_CORE_GET_FRAME_HEIGHT, &frame_height,
|
||||
META_CORE_GET_FRAME_RECT, &frame_rect,
|
||||
META_CORE_GET_END);
|
||||
|
||||
meta_theme_get_frame_borders (meta_theme_get_current (),
|
||||
@@ -1625,8 +1624,8 @@ clip_region_to_visible_frame_border (cairo_region_t *region,
|
||||
/* Visible frame rect */
|
||||
area.x = borders.invisible.left;
|
||||
area.y = borders.invisible.top;
|
||||
area.width = frame_width - borders.invisible.left - borders.invisible.right;
|
||||
area.height = frame_height - borders.invisible.top - borders.invisible.bottom;
|
||||
area.width = frame_rect.width;
|
||||
area.height = frame_rect.height;
|
||||
|
||||
frame_border = cairo_region_create_rectangle (&area);
|
||||
|
||||
|
||||
@@ -383,9 +383,13 @@ handle_scroll_event (MetaWaylandPointer *pointer,
|
||||
case CLUTTER_SCROLL_SMOOTH:
|
||||
{
|
||||
double dx, dy;
|
||||
/* Clutter smooth scroll events are in discrete steps (1 step = 1.0 long
|
||||
* vector along one axis). To convert to smooth scroll events that are
|
||||
* in pointer motion event space, multiply the vector with the 10. */
|
||||
const double factor = 10.0;
|
||||
clutter_event_get_scroll_delta (event, &dx, &dy);
|
||||
x_value = wl_fixed_from_double (dx);
|
||||
y_value = wl_fixed_from_double (dy);
|
||||
x_value = wl_fixed_from_double (dx) * factor;
|
||||
y_value = wl_fixed_from_double (dy) * factor;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -1018,9 +1018,9 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
|
||||
}
|
||||
|
||||
window = meta_window_wayland_new (meta_get_display (), surface);
|
||||
meta_window_move (window, FALSE,
|
||||
parent_surf->window->rect.x + x,
|
||||
parent_surf->window->rect.y + y);
|
||||
meta_window_move_frame (window, FALSE,
|
||||
parent_surf->window->rect.x + x,
|
||||
parent_surf->window->rect.y + y);
|
||||
window->showing_for_first_time = FALSE;
|
||||
window->placed = TRUE;
|
||||
meta_window_set_transient_for (window, parent_surf->window);
|
||||
@@ -1212,9 +1212,9 @@ wl_shell_surface_set_transient (struct wl_client *client,
|
||||
wl_shell_surface_set_state (surface, SURFACE_STATE_TOPLEVEL);
|
||||
|
||||
meta_window_set_transient_for (surface->window, parent_surf->window);
|
||||
meta_window_move (surface->window, FALSE,
|
||||
parent_surf->window->rect.x + x,
|
||||
parent_surf->window->rect.y + y);
|
||||
meta_window_move_frame (surface->window, FALSE,
|
||||
parent_surf->window->rect.x + x,
|
||||
parent_surf->window->rect.y + y);
|
||||
surface->window->placed = TRUE;
|
||||
}
|
||||
|
||||
@@ -1247,9 +1247,9 @@ wl_shell_surface_set_popup (struct wl_client *client,
|
||||
wl_shell_surface_set_state (surface, SURFACE_STATE_TOPLEVEL);
|
||||
|
||||
meta_window_set_transient_for (surface->window, parent_surf->window);
|
||||
meta_window_move (surface->window, FALSE,
|
||||
parent_surf->window->rect.x + x,
|
||||
parent_surf->window->rect.y + y);
|
||||
meta_window_move_frame (surface->window, FALSE,
|
||||
parent_surf->window->rect.x + x,
|
||||
parent_surf->window->rect.y + y);
|
||||
surface->window->placed = TRUE;
|
||||
|
||||
meta_wayland_pointer_start_popup_grab (&seat->pointer, surface);
|
||||
|
||||
@@ -55,6 +55,10 @@ struct _MetaWindowX11Private
|
||||
int border_width;
|
||||
|
||||
MetaResizePopup *grab_resize_popup;
|
||||
|
||||
/* These are in server coordinates. If we have a frame, it's
|
||||
* relative to the frame. */
|
||||
MetaRectangle client_rect;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -210,8 +210,8 @@ send_configure_notify (MetaWindow *window)
|
||||
event.xconfigure.display = window->display->xdisplay;
|
||||
event.xconfigure.event = window->xwindow;
|
||||
event.xconfigure.window = window->xwindow;
|
||||
event.xconfigure.x = window->rect.x - priv->border_width;
|
||||
event.xconfigure.y = window->rect.y - priv->border_width;
|
||||
event.xconfigure.x = priv->client_rect.x - priv->border_width;
|
||||
event.xconfigure.y = priv->client_rect.y - priv->border_width;
|
||||
if (window->frame)
|
||||
{
|
||||
if (window->withdrawn)
|
||||
@@ -233,8 +233,8 @@ send_configure_notify (MetaWindow *window)
|
||||
event.xconfigure.y += window->frame->rect.y;
|
||||
}
|
||||
}
|
||||
event.xconfigure.width = window->rect.width;
|
||||
event.xconfigure.height = window->rect.height;
|
||||
event.xconfigure.width = priv->client_rect.width;
|
||||
event.xconfigure.height = priv->client_rect.height;
|
||||
event.xconfigure.border_width = priv->border_width; /* requested not actual */
|
||||
event.xconfigure.above = None; /* FIXME */
|
||||
event.xconfigure.override_redirect = False;
|
||||
@@ -492,6 +492,7 @@ meta_window_apply_session_info (MetaWindow *window,
|
||||
flags = META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||
|
||||
adjust_for_gravity (window, FALSE, gravity, &rect);
|
||||
meta_window_client_rect_to_frame_rect (window, &rect, &rect);
|
||||
meta_window_move_resize_internal (window, flags, gravity, rect);
|
||||
}
|
||||
}
|
||||
@@ -500,7 +501,6 @@ static void
|
||||
meta_window_x11_manage (MetaWindow *window)
|
||||
{
|
||||
MetaDisplay *display = window->display;
|
||||
MetaMoveResizeFlags flags;
|
||||
|
||||
meta_display_register_x_window (display, &window->xwindow, window);
|
||||
meta_window_x11_update_shape_region (window);
|
||||
@@ -518,6 +518,9 @@ meta_window_x11_manage (MetaWindow *window)
|
||||
|
||||
meta_window_x11_update_net_wm_type (window);
|
||||
|
||||
if (window->decorated)
|
||||
meta_window_ensure_frame (window);
|
||||
|
||||
/* Now try applying saved stuff from the session */
|
||||
{
|
||||
const MetaWindowSessionInfo *info;
|
||||
@@ -535,10 +538,10 @@ meta_window_x11_manage (MetaWindow *window)
|
||||
* passing TRUE for is_configure_request, ICCCM says
|
||||
* initial map is handled same as configure request
|
||||
*/
|
||||
flags = META_IS_CONFIGURE_REQUEST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||
if (!window->override_redirect)
|
||||
{
|
||||
MetaRectangle rect;
|
||||
MetaMoveResizeFlags flags;
|
||||
int gravity = window->size_hints.win_gravity;
|
||||
|
||||
rect.x = window->size_hints.x;
|
||||
@@ -546,7 +549,10 @@ meta_window_x11_manage (MetaWindow *window)
|
||||
rect.width = window->size_hints.width;
|
||||
rect.height = window->size_hints.height;
|
||||
|
||||
flags = META_IS_CONFIGURE_REQUEST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||
|
||||
adjust_for_gravity (window, TRUE, gravity, &rect);
|
||||
meta_window_client_rect_to_frame_rect (window, &rect, &rect);
|
||||
meta_window_move_resize_internal (window, flags, gravity, rect);
|
||||
}
|
||||
}
|
||||
@@ -644,6 +650,9 @@ meta_window_x11_unmanage (MetaWindow *window)
|
||||
meta_display_ungrab_focus_window_button (window->display, window);
|
||||
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
if (window->frame)
|
||||
meta_window_destroy_frame (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -785,6 +794,22 @@ meta_window_x11_focus (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_get_client_root_coords (MetaWindow *window,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
|
||||
*rect = priv->client_rect;
|
||||
|
||||
if (window->frame)
|
||||
{
|
||||
rect->x += window->frame->rect.x;
|
||||
rect->y += window->frame->rect.y;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_refresh_resize_popup (MetaWindow *window)
|
||||
{
|
||||
@@ -1003,9 +1028,7 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
MetaFrameBorders borders;
|
||||
int root_x_nw, root_y_nw;
|
||||
int w, h;
|
||||
int client_move_x, client_move_y;
|
||||
MetaRectangle client_rect;
|
||||
int size_dx, size_dy;
|
||||
XWindowChanges values;
|
||||
unsigned int mask;
|
||||
@@ -1021,32 +1044,22 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
||||
|
||||
is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0;
|
||||
|
||||
/* meta_window_constrain() might have maximized the window after placement,
|
||||
* changing the borders.
|
||||
*/
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
|
||||
root_x_nw = constrained_rect.x;
|
||||
root_y_nw = constrained_rect.y;
|
||||
w = constrained_rect.width;
|
||||
h = constrained_rect.height;
|
||||
size_dx = constrained_rect.x - window->rect.width;
|
||||
size_dy = constrained_rect.y - window->rect.height;
|
||||
|
||||
size_dx = w - window->rect.width;
|
||||
size_dy = h - window->rect.height;
|
||||
|
||||
if (size_dx != 0 || size_dy != 0)
|
||||
need_resize_client = TRUE;
|
||||
|
||||
window->rect.width = w;
|
||||
window->rect.height = h;
|
||||
window->rect = constrained_rect;
|
||||
|
||||
if (window->frame)
|
||||
{
|
||||
int new_w, new_h;
|
||||
int new_x, new_y;
|
||||
|
||||
new_w = window->rect.width + borders.total.left + borders.total.right;
|
||||
/* Compute new frame size */
|
||||
new_w = window->rect.width + borders.invisible.left + borders.invisible.right;
|
||||
|
||||
new_h = borders.total.top + borders.total.bottom;
|
||||
new_h = borders.invisible.top + borders.invisible.bottom;
|
||||
if (!window->shaded)
|
||||
new_h += window->rect.height;
|
||||
|
||||
@@ -1058,19 +1071,9 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
||||
window->frame->rect.height = new_h;
|
||||
}
|
||||
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Calculated frame size %dx%d\n",
|
||||
window->frame->rect.width,
|
||||
window->frame->rect.height);
|
||||
}
|
||||
|
||||
if (window->frame)
|
||||
{
|
||||
int new_x, new_y;
|
||||
|
||||
/* Compute new frame coords */
|
||||
new_x = root_x_nw - borders.total.left;
|
||||
new_y = root_y_nw - borders.total.top;
|
||||
new_x = window->rect.x - borders.invisible.left;
|
||||
new_y = window->rect.y - borders.invisible.top;
|
||||
|
||||
if (new_x != window->frame->rect.x ||
|
||||
new_y != window->frame->rect.y)
|
||||
@@ -1079,22 +1082,35 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
||||
window->frame->rect.x = new_x;
|
||||
window->frame->rect.y = new_y;
|
||||
}
|
||||
|
||||
client_move_x = borders.total.left;
|
||||
client_move_y = borders.total.top;
|
||||
}
|
||||
else
|
||||
|
||||
/* Calculate the new client rect */
|
||||
meta_window_frame_rect_to_client_rect (window, &constrained_rect, &client_rect);
|
||||
|
||||
/* The above client_rect is in root window coordinates. The
|
||||
* values we need to pass to XConfigureWindow are in parent
|
||||
* coordinates, so if the window is in a frame, we need to
|
||||
* correct the x/y positions here. */
|
||||
if (window->frame)
|
||||
{
|
||||
client_move_x = root_x_nw;
|
||||
client_move_y = root_y_nw;
|
||||
client_rect.x = borders.total.left;
|
||||
client_rect.y = borders.total.top;
|
||||
}
|
||||
|
||||
if (client_move_x != window->rect.x ||
|
||||
client_move_y != window->rect.y)
|
||||
if (client_rect.x != priv->client_rect.x ||
|
||||
client_rect.y != priv->client_rect.y)
|
||||
{
|
||||
need_move_client = TRUE;
|
||||
window->rect.x = client_move_x;
|
||||
window->rect.y = client_move_y;
|
||||
priv->client_rect.x = client_rect.x;
|
||||
priv->client_rect.y = client_rect.y;
|
||||
}
|
||||
|
||||
if (client_rect.width != priv->client_rect.width ||
|
||||
client_rect.height != priv->client_rect.height)
|
||||
{
|
||||
need_resize_client = TRUE;
|
||||
priv->client_rect.width = client_rect.width;
|
||||
priv->client_rect.height = client_rect.height;
|
||||
}
|
||||
|
||||
/* If frame extents have changed, fill in other frame fields and
|
||||
@@ -1186,10 +1202,10 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
||||
need_move_frame, need_resize_frame);
|
||||
|
||||
values.border_width = 0;
|
||||
values.x = client_move_x;
|
||||
values.y = client_move_y;
|
||||
values.width = window->rect.width;
|
||||
values.height = window->rect.height;
|
||||
values.x = client_rect.x;
|
||||
values.y = client_rect.y;
|
||||
values.width = client_rect.width;
|
||||
values.height = client_rect.height;
|
||||
|
||||
mask = 0;
|
||||
if (is_configure_request && priv->border_width != 0)
|
||||
@@ -1768,6 +1784,8 @@ void
|
||||
meta_window_x11_update_input_region (MetaWindow *window)
|
||||
{
|
||||
cairo_region_t *region = NULL;
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
|
||||
/* Decorated windows don't have an input region, because
|
||||
we don't shape the frame to match the client windows
|
||||
@@ -1804,8 +1822,8 @@ meta_window_x11_update_input_region (MetaWindow *window)
|
||||
(n_rects == 1 &&
|
||||
(rects[0].x != 0 ||
|
||||
rects[0].y != 0 ||
|
||||
rects[0].width != window->rect.width ||
|
||||
rects[0].height != window->rect.height)))
|
||||
rects[0].width != priv->client_rect.width ||
|
||||
rects[0].height != priv->client_rect.height)))
|
||||
region = region_create_from_x_rectangles (rects, n_rects);
|
||||
|
||||
XFree (rects);
|
||||
@@ -1818,8 +1836,8 @@ meta_window_x11_update_input_region (MetaWindow *window)
|
||||
|
||||
client_area.x = 0;
|
||||
client_area.y = 0;
|
||||
client_area.width = window->rect.width;
|
||||
client_area.height = window->rect.height;
|
||||
client_area.width = priv->client_rect.width;
|
||||
client_area.height = priv->client_rect.height;
|
||||
|
||||
/* The shape we get back from the client may have coordinates
|
||||
* outside of the frame. The X SHAPE Extension requires that
|
||||
@@ -1850,6 +1868,8 @@ meta_window_set_shape_region (MetaWindow *window,
|
||||
void
|
||||
meta_window_x11_update_shape_region (MetaWindow *window)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
cairo_region_t *region = NULL;
|
||||
|
||||
if (META_DISPLAY_HAS_SHAPE (window->display))
|
||||
@@ -1893,8 +1913,8 @@ meta_window_x11_update_shape_region (MetaWindow *window)
|
||||
|
||||
client_area.x = 0;
|
||||
client_area.y = 0;
|
||||
client_area.width = window->rect.width;
|
||||
client_area.height = window->rect.height;
|
||||
client_area.width = priv->client_rect.width;
|
||||
client_area.height = priv->client_rect.height;
|
||||
|
||||
/* The shape we get back from the client may have coordinates
|
||||
* outside of the frame. The X SHAPE Extension requires that
|
||||
@@ -2080,6 +2100,7 @@ meta_window_move_resize_request (MetaWindow *window,
|
||||
rect.height = height;
|
||||
|
||||
adjust_for_gravity (window, TRUE, gravity, &rect);
|
||||
meta_window_client_rect_to_frame_rect (window, &rect, &rect);
|
||||
meta_window_move_resize_internal (window, flags, gravity, rect);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user