Compare commits
16 Commits
3.13.4
...
wip/gestur
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3ed80495e0 | ||
![]() |
f13c86d651 | ||
![]() |
be2ca66735 | ||
![]() |
2df807549e | ||
![]() |
66cdb1bb71 | ||
![]() |
8030a2972e | ||
![]() |
ba086dea8c | ||
![]() |
6a02d7dfa3 | ||
![]() |
c5db56da5c | ||
![]() |
b5c605df5e | ||
![]() |
4ad2865cce | ||
![]() |
b9687d1a72 | ||
![]() |
66d18fcc55 | ||
![]() |
321cd5d85f | ||
![]() |
ae91de5d03 | ||
![]() |
7247b8d81b |
11
.gitignore
vendored
11
.gitignore
vendored
@@ -43,7 +43,6 @@ POTFILES
|
||||
po/*.pot
|
||||
libmutter.pc
|
||||
mutter
|
||||
mutter-restart-helper
|
||||
org.gnome.mutter.gschema.valid
|
||||
org.gnome.mutter.gschema.xml
|
||||
org.gnome.mutter.wayland.gschema.valid
|
||||
@@ -52,6 +51,16 @@ testasyncgetprop
|
||||
testboxes
|
||||
testgradient
|
||||
m4/*
|
||||
mutter-grayscale
|
||||
mutter-mag
|
||||
mutter-message
|
||||
mutter-window-demo
|
||||
focus-window
|
||||
test-attached
|
||||
test-focus
|
||||
test-gravity
|
||||
test-resizing
|
||||
test-size-hints
|
||||
INSTALL
|
||||
mkinstalldirs
|
||||
src/mutter-enum-types.[ch]
|
||||
|
21
NEWS
21
NEWS
@@ -1,24 +1,3 @@
|
||||
3.13.4
|
||||
======
|
||||
* Fix move/resize operations for wayland clients [Marek; #731237]
|
||||
* Add ::first-frame signal to MetaWindowActor [Owen; #732343]
|
||||
* Handle keysyms without the XF86 prefix [Owen; #727993]
|
||||
* Add touch gesture support [Carlos]
|
||||
* Fix a deadlock when exiting [Owen; #733068]
|
||||
* Add framework for restarting the compositor with nice visuals
|
||||
[Owen; #733026]
|
||||
* Toggle seat capabilities on VT switch [Carlos; #733563]
|
||||
* Misc bug fixes [Florian, Owen; #732695, #732350]
|
||||
|
||||
Contributors:
|
||||
Tom Beckmann, Giovanni Campagna, Marek Chalupa, Adel Gadllah,
|
||||
Carlos Garnacho, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz,
|
||||
Owen W. Taylor
|
||||
|
||||
Translations:
|
||||
Yuri Myasoedov [ru], Fran Diéguez [gl], Aurimas Černius [lt], MarMav [el],
|
||||
Enrico Nicoletto [pt_BR]
|
||||
|
||||
3.13.3
|
||||
======
|
||||
* Improve behavior of window buttons with compositor menus [Florian; #731058]
|
||||
|
@@ -2,7 +2,7 @@ AC_PREREQ(2.62)
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [13])
|
||||
m4_define([mutter_micro_version], [4])
|
||||
m4_define([mutter_micro_version], [3])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@@ -72,18 +72,17 @@ CLUTTER_PACKAGE=clutter-1.0
|
||||
|
||||
MUTTER_PC_MODULES="
|
||||
gtk+-3.0 >= 3.9.11
|
||||
gio-unix-2.0 >= 2.25.10
|
||||
gio-2.0 >= 2.25.10
|
||||
pango >= 1.2.0
|
||||
cairo >= 1.10.0
|
||||
gsettings-desktop-schemas >= 3.7.3
|
||||
xcomposite >= 0.2 xfixes xext xdamage xi >= 1.6.0
|
||||
xcursor
|
||||
$CLUTTER_PACKAGE >= 1.19.5
|
||||
$CLUTTER_PACKAGE >= 1.17.5
|
||||
clutter-wayland-1.0
|
||||
clutter-wayland-compositor-1.0
|
||||
clutter-egl-1.0
|
||||
cogl-1.0 >= 1.17.1
|
||||
libinput
|
||||
wayland-server >= 1.4.93
|
||||
upower-glib >= 0.99.0
|
||||
gnome-desktop-3.0
|
||||
|
1283
po/pt_BR.po
1283
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
@@ -10,8 +10,6 @@ AM_CPPFLAGS = \
|
||||
-DCLUTTER_ENABLE_EXPERIMENTAL_API \
|
||||
-DCOGL_ENABLE_EXPERIMENTAL_API \
|
||||
-DCOGL_ENABLE_EXPERIMENTAL_2_0_API \
|
||||
-DCLUTTER_DISABLE_DEPRECATION_WARNINGS \
|
||||
-DCOGL_DISABLE_DEPRECATION_WARNINGS \
|
||||
$(MUTTER_CFLAGS) \
|
||||
$(MUTTER_NATIVE_BACKEND_CFLAGS) \
|
||||
-I$(builddir) \
|
||||
@@ -154,8 +152,8 @@ libmutter_la_SOURCES = \
|
||||
core/frame.h \
|
||||
ui/gradient.c \
|
||||
meta/gradient.h \
|
||||
core/meta-gesture-tracker.c \
|
||||
core/meta-gesture-tracker-private.h \
|
||||
core/gesture-tracker.c \
|
||||
core/gesture-tracker-private.h \
|
||||
core/keybindings.c \
|
||||
core/keybindings-private.h \
|
||||
core/main.c \
|
||||
@@ -167,7 +165,6 @@ libmutter_la_SOURCES = \
|
||||
core/screen-private.h \
|
||||
meta/screen.h \
|
||||
meta/types.h \
|
||||
core/restart.c \
|
||||
core/stack.c \
|
||||
core/stack.h \
|
||||
core/stack-tracker.c \
|
||||
@@ -317,10 +314,6 @@ bin_PROGRAMS=mutter
|
||||
mutter_SOURCES = core/mutter.c
|
||||
mutter_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
|
||||
libexec_PROGRAMS = mutter-restart-helper
|
||||
mutter_restart_helper_SOURCES = core/restart-helper.c
|
||||
mutter_restart_helper_LDADD = $(MUTTER_LIBS)
|
||||
|
||||
if HAVE_INTROSPECTION
|
||||
include $(INTROSPECTION_MAKEFILE)
|
||||
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#define META_CURSOR_TRACKER_PRIVATE_H
|
||||
|
||||
#include <meta/meta-cursor-tracker.h>
|
||||
#include <wayland-server.h>
|
||||
#include <gbm.h>
|
||||
|
||||
#include "meta-cursor.h"
|
||||
#include "meta-cursor-renderer.h"
|
||||
@@ -30,6 +32,7 @@
|
||||
struct _MetaCursorTracker {
|
||||
GObject parent_instance;
|
||||
|
||||
MetaScreen *screen;
|
||||
MetaCursorRenderer *renderer;
|
||||
|
||||
gboolean is_showing;
|
||||
|
@@ -44,6 +44,9 @@
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "screen-private.h"
|
||||
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
|
||||
|
||||
@@ -57,12 +60,10 @@ static guint signals[LAST_SIGNAL];
|
||||
static MetaCursorReference *
|
||||
get_displayed_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
if (!tracker->is_showing)
|
||||
return NULL;
|
||||
|
||||
if (display->grab_op == META_GRAB_OP_NONE)
|
||||
if (tracker->screen->display->grab_op == META_GRAB_OP_NONE)
|
||||
{
|
||||
if (tracker->has_window_cursor)
|
||||
return tracker->window_cursor;
|
||||
@@ -96,9 +97,6 @@ sync_cursor (MetaCursorTracker *tracker)
|
||||
static void
|
||||
meta_cursor_tracker_init (MetaCursorTracker *self)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
self->renderer = meta_backend_get_cursor_renderer (backend);
|
||||
self->is_showing = TRUE;
|
||||
}
|
||||
|
||||
@@ -131,9 +129,47 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
|
||||
}
|
||||
|
||||
static MetaCursorTracker *
|
||||
meta_cursor_tracker_new (void)
|
||||
make_wayland_cursor_tracker (MetaScreen *screen)
|
||||
{
|
||||
return g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaWaylandCompositor *compositor;
|
||||
MetaCursorTracker *self;
|
||||
|
||||
self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
|
||||
self->screen = screen;
|
||||
self->renderer = meta_backend_get_cursor_renderer (backend);
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
compositor->seat->pointer.cursor_tracker = self;
|
||||
meta_cursor_tracker_update_position (self, 0, 0);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static MetaCursorTracker *
|
||||
make_x11_cursor_tracker (MetaScreen *screen)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaCursorTracker *self;
|
||||
|
||||
self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
|
||||
self->screen = screen;
|
||||
self->renderer = meta_backend_get_cursor_renderer (backend);
|
||||
|
||||
XFixesSelectCursorInput (screen->display->xdisplay,
|
||||
screen->xroot,
|
||||
XFixesDisplayCursorNotifyMask);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static MetaCursorTracker *
|
||||
meta_cursor_tracker_new (MetaScreen *screen)
|
||||
{
|
||||
if (meta_is_wayland_compositor ())
|
||||
return make_wayland_cursor_tracker (screen);
|
||||
else
|
||||
return make_x11_cursor_tracker (screen);
|
||||
}
|
||||
|
||||
static MetaCursorTracker *_cursor_tracker;
|
||||
@@ -150,7 +186,7 @@ MetaCursorTracker *
|
||||
meta_cursor_tracker_get_for_screen (MetaScreen *screen)
|
||||
{
|
||||
if (!_cursor_tracker)
|
||||
_cursor_tracker = meta_cursor_tracker_new ();
|
||||
_cursor_tracker = meta_cursor_tracker_new (screen);
|
||||
|
||||
return _cursor_tracker;
|
||||
}
|
||||
@@ -171,13 +207,12 @@ gboolean
|
||||
meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
XEvent *xevent)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
XFixesCursorNotifyEvent *notify_event;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
return FALSE;
|
||||
|
||||
if (xevent->xany.type != display->xfixes_event_base + XFixesCursorNotify)
|
||||
if (xevent->xany.type != tracker->screen->display->xfixes_event_base + XFixesCursorNotify)
|
||||
return FALSE;
|
||||
|
||||
notify_event = (XFixesCursorNotifyEvent *)xevent;
|
||||
@@ -208,7 +243,6 @@ meta_cursor_reference_take_texture (CoglTexture2D *texture,
|
||||
static void
|
||||
ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
XFixesCursorImage *cursor_image;
|
||||
CoglTexture2D *sprite;
|
||||
guint8 *cursor_data;
|
||||
@@ -218,7 +252,7 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
if (tracker->xfixes_cursor)
|
||||
return;
|
||||
|
||||
cursor_image = XFixesGetCursorImage (display->xdisplay);
|
||||
cursor_image = XFixesGetCursorImage (tracker->screen->display->xdisplay);
|
||||
if (!cursor_image)
|
||||
return;
|
||||
|
||||
|
@@ -60,7 +60,7 @@ typedef struct {
|
||||
gboolean enabled;
|
||||
MetaRectangle rect;
|
||||
float refresh_rate;
|
||||
MetaMonitorTransform transform;
|
||||
enum wl_output_transform transform;
|
||||
|
||||
gboolean is_primary;
|
||||
gboolean is_presentation;
|
||||
@@ -656,20 +656,20 @@ handle_text (GMarkupParseContext *context,
|
||||
else if (strcmp (parser->output_field, "rotation") == 0)
|
||||
{
|
||||
if (strncmp (text, "normal", text_len) == 0)
|
||||
parser->output.transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
parser->output.transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
else if (strncmp (text, "left", text_len) == 0)
|
||||
parser->output.transform = META_MONITOR_TRANSFORM_90;
|
||||
parser->output.transform = WL_OUTPUT_TRANSFORM_90;
|
||||
else if (strncmp (text, "upside_down", text_len) == 0)
|
||||
parser->output.transform = META_MONITOR_TRANSFORM_180;
|
||||
parser->output.transform = WL_OUTPUT_TRANSFORM_180;
|
||||
else if (strncmp (text, "right", text_len) == 0)
|
||||
parser->output.transform = META_MONITOR_TRANSFORM_270;
|
||||
parser->output.transform = WL_OUTPUT_TRANSFORM_270;
|
||||
else
|
||||
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"Invalid rotation type %.*s", (int)text_len, text);
|
||||
}
|
||||
else if (strcmp (parser->output_field, "reflect_x") == 0)
|
||||
parser->output.transform += read_bool (text, text_len, error) ?
|
||||
META_MONITOR_TRANSFORM_FLIPPED : 0;
|
||||
WL_OUTPUT_TRANSFORM_FLIPPED : 0;
|
||||
else if (strcmp (parser->output_field, "reflect_y") == 0)
|
||||
{
|
||||
/* FIXME (look at the rotation map in monitor.c) */
|
||||
@@ -1115,7 +1115,7 @@ make_default_config (MetaMonitorConfig *self,
|
||||
ret->outputs[0].rect.width = outputs[0].preferred_mode->width;
|
||||
ret->outputs[0].rect.height = outputs[0].preferred_mode->height;
|
||||
ret->outputs[0].refresh_rate = outputs[0].preferred_mode->refresh_rate;
|
||||
ret->outputs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[0].transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
ret->outputs[0].is_primary = TRUE;
|
||||
|
||||
return ret;
|
||||
@@ -1167,7 +1167,7 @@ make_default_config (MetaMonitorConfig *self,
|
||||
ret->outputs[j].rect.width = outputs[0].preferred_mode->width;
|
||||
ret->outputs[j].rect.height = outputs[0].preferred_mode->height;
|
||||
ret->outputs[j].refresh_rate = outputs[0].preferred_mode->refresh_rate;
|
||||
ret->outputs[j].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[j].transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
ret->outputs[j].is_primary = FALSE;
|
||||
ret->outputs[j].is_presentation = FALSE;
|
||||
}
|
||||
@@ -1202,7 +1202,7 @@ make_default_config (MetaMonitorConfig *self,
|
||||
ret->outputs[i].rect.width = output->preferred_mode->width;
|
||||
ret->outputs[i].rect.height = output->preferred_mode->height;
|
||||
ret->outputs[i].refresh_rate = output->preferred_mode->refresh_rate;
|
||||
ret->outputs[i].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[i].transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
ret->outputs[i].is_primary = (output == primary);
|
||||
|
||||
/* Disable outputs that would go beyond framebuffer limits */
|
||||
@@ -1250,7 +1250,7 @@ ensure_at_least_one_output (MetaMonitorConfig *self,
|
||||
ret->outputs[i].rect.width = output->preferred_mode->width;
|
||||
ret->outputs[i].rect.height = output->preferred_mode->height;
|
||||
ret->outputs[i].refresh_rate = output->preferred_mode->refresh_rate;
|
||||
ret->outputs[i].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[i].transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
ret->outputs[i].is_primary = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -1512,7 +1512,7 @@ meta_monitor_config_save (MetaMonitorConfig *self)
|
||||
output->rect.x,
|
||||
output->rect.y,
|
||||
rotation_map[output->transform & 0x3],
|
||||
output->transform >= META_MONITOR_TRANSFORM_FLIPPED ? "yes" : "no",
|
||||
output->transform >= WL_OUTPUT_TRANSFORM_FLIPPED ? "yes" : "no",
|
||||
output->is_primary ? "yes" : "no",
|
||||
output->is_presentation ? "yes" : "no");
|
||||
}
|
||||
@@ -1621,13 +1621,13 @@ output_supports_mode (MetaOutput *output,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
crtc_assignment_assign (CrtcAssignment *assign,
|
||||
MetaCRTC *crtc,
|
||||
MetaMonitorMode *mode,
|
||||
int x,
|
||||
int y,
|
||||
MetaMonitorTransform transform,
|
||||
MetaOutput *output)
|
||||
crtc_assignment_assign (CrtcAssignment *assign,
|
||||
MetaCRTC *crtc,
|
||||
MetaMonitorMode *mode,
|
||||
int x,
|
||||
int y,
|
||||
enum wl_output_transform transform,
|
||||
MetaOutput *output)
|
||||
{
|
||||
MetaCRTCInfo *info = g_hash_table_lookup (assign->info, crtc);
|
||||
|
||||
|
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "meta-monitor-manager-dummy.h"
|
||||
|
||||
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
|
||||
struct _MetaMonitorManagerDummy
|
||||
{
|
||||
@@ -66,8 +66,8 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
|
||||
manager->crtcs[0].rect.width = manager->modes[0].width;
|
||||
manager->crtcs[0].rect.height = manager->modes[0].height;
|
||||
manager->crtcs[0].current_mode = &manager->modes[0];
|
||||
manager->crtcs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
manager->crtcs[0].all_transforms = ALL_TRANSFORMS;
|
||||
manager->crtcs[0].transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
manager->crtcs[0].all_transforms = ALL_WL_TRANSFORMS;
|
||||
manager->crtcs[0].is_dirty = FALSE;
|
||||
manager->crtcs[0].logical_monitor = NULL;
|
||||
|
||||
@@ -75,7 +75,7 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
|
||||
manager->n_outputs = 1;
|
||||
|
||||
manager->outputs[0].crtc = &manager->crtcs[0];
|
||||
manager->outputs[0].winsys_id = 1;
|
||||
manager->outputs[0].output_id = 1;
|
||||
manager->outputs[0].name = g_strdup ("LVDS");
|
||||
manager->outputs[0].vendor = g_strdup ("MetaProducts Inc.");
|
||||
manager->outputs[0].product = g_strdup ("unknown");
|
||||
|
@@ -125,7 +125,7 @@ make_logical_config (MetaMonitorManager *manager)
|
||||
*/
|
||||
info.is_presentation = TRUE;
|
||||
info.in_fullscreen = -1;
|
||||
info.winsys_id = 0;
|
||||
info.output_id = 0;
|
||||
|
||||
g_array_append_val (monitor_infos, info);
|
||||
|
||||
@@ -156,8 +156,8 @@ make_logical_config (MetaMonitorManager *manager)
|
||||
info->is_primary = info->is_primary || output->is_primary;
|
||||
info->is_presentation = info->is_presentation && output->is_presentation;
|
||||
|
||||
if (output->is_primary || info->winsys_id == 0)
|
||||
info->winsys_id = output->winsys_id;
|
||||
if (output->is_primary || info->output_id == 0)
|
||||
info->output_id = output->output_id;
|
||||
|
||||
if (info->is_primary)
|
||||
manager->primary_monitor_index = info->number;
|
||||
@@ -477,7 +477,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
GVariantBuilder transforms;
|
||||
|
||||
g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
|
||||
for (j = 0; j <= META_MONITOR_TRANSFORM_FLIPPED_270; j++)
|
||||
for (j = 0; j <= WL_OUTPUT_TRANSFORM_FLIPPED_270; j++)
|
||||
if (crtc->all_transforms & (1 << j))
|
||||
g_variant_builder_add (&transforms, "u", j);
|
||||
|
||||
@@ -560,7 +560,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
|
||||
g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
|
||||
i, /* ID */
|
||||
(gint64)output->winsys_id,
|
||||
(gint64)output->output_id,
|
||||
(int)(output->crtc ? output->crtc - manager->crtcs : -1),
|
||||
&crtcs,
|
||||
output->name,
|
||||
@@ -667,7 +667,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
int new_mode, x, y;
|
||||
int new_screen_width, new_screen_height;
|
||||
guint transform;
|
||||
guint output_index;
|
||||
guint output_id;
|
||||
GPtrArray *crtc_infos, *output_infos;
|
||||
|
||||
if (serial != manager->serial)
|
||||
@@ -694,6 +694,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
MetaOutput *first_output;
|
||||
MetaCRTC *crtc;
|
||||
MetaMonitorMode *mode;
|
||||
guint output_id;
|
||||
|
||||
crtc_info = g_slice_new (MetaCRTCInfo);
|
||||
crtc_info->outputs = g_ptr_array_new ();
|
||||
@@ -755,8 +756,8 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
crtc_info->y = 0;
|
||||
}
|
||||
|
||||
if (transform < META_MONITOR_TRANSFORM_NORMAL ||
|
||||
transform > META_MONITOR_TRANSFORM_FLIPPED_270 ||
|
||||
if (transform < WL_OUTPUT_TRANSFORM_NORMAL ||
|
||||
transform > WL_OUTPUT_TRANSFORM_FLIPPED_270 ||
|
||||
((crtc->all_transforms & (1 << transform)) == 0))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
@@ -767,18 +768,18 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
crtc_info->transform = transform;
|
||||
|
||||
first_output = NULL;
|
||||
while (g_variant_iter_loop (nested_outputs, "u", &output_index))
|
||||
while (g_variant_iter_loop (nested_outputs, "u", &output_id))
|
||||
{
|
||||
MetaOutput *output;
|
||||
|
||||
if (output_index >= manager->n_outputs)
|
||||
if (output_id >= manager->n_outputs)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_INVALID_ARGS,
|
||||
"Invalid output id");
|
||||
return TRUE;
|
||||
}
|
||||
output = &manager->outputs[output_index];
|
||||
output = &manager->outputs[output_id];
|
||||
|
||||
if (!output_can_config (output, crtc, mode))
|
||||
{
|
||||
@@ -823,12 +824,12 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
}
|
||||
|
||||
g_variant_iter_init (&output_iter, outputs);
|
||||
while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_index, &properties))
|
||||
while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_id, &properties))
|
||||
{
|
||||
MetaOutputInfo *output_info;
|
||||
gboolean primary, presentation;
|
||||
|
||||
if (output_index >= manager->n_outputs)
|
||||
if (output_id >= manager->n_outputs)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_INVALID_ARGS,
|
||||
@@ -837,7 +838,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
}
|
||||
|
||||
output_info = g_slice_new0 (MetaOutputInfo);
|
||||
output_info->output = &manager->outputs[output_index];
|
||||
output_info->output = &manager->outputs[output_id];
|
||||
|
||||
if (g_variant_lookup (properties, "primary", "b", &primary))
|
||||
output_info->is_primary = primary;
|
||||
@@ -908,7 +909,7 @@ static gboolean
|
||||
meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton,
|
||||
GDBusMethodInvocation *invocation,
|
||||
guint serial,
|
||||
guint output_index,
|
||||
guint output_id,
|
||||
gint value)
|
||||
{
|
||||
MetaMonitorManager *manager = META_MONITOR_MANAGER (skeleton);
|
||||
@@ -922,14 +923,14 @@ meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (output_index >= manager->n_outputs)
|
||||
if (output_id >= manager->n_outputs)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_INVALID_ARGS,
|
||||
"Invalid output id");
|
||||
return TRUE;
|
||||
}
|
||||
output = &manager->outputs[output_index];
|
||||
output = &manager->outputs[output_id];
|
||||
|
||||
if (value < 0 || value > 100)
|
||||
{
|
||||
|
@@ -42,6 +42,7 @@
|
||||
#include <meta/screen.h>
|
||||
#include "stack-tracker.h"
|
||||
#include "ui.h"
|
||||
#include <wayland-server.h>
|
||||
|
||||
#include "meta-display-config-shared.h"
|
||||
#include "meta-dbus-display-config.h"
|
||||
@@ -59,23 +60,12 @@ typedef struct _MetaMonitorInfo MetaMonitorInfo;
|
||||
typedef struct _MetaCRTCInfo MetaCRTCInfo;
|
||||
typedef struct _MetaOutputInfo MetaOutputInfo;
|
||||
|
||||
typedef enum {
|
||||
META_MONITOR_TRANSFORM_NORMAL,
|
||||
META_MONITOR_TRANSFORM_90,
|
||||
META_MONITOR_TRANSFORM_180,
|
||||
META_MONITOR_TRANSFORM_270,
|
||||
META_MONITOR_TRANSFORM_FLIPPED,
|
||||
META_MONITOR_TRANSFORM_FLIPPED_90,
|
||||
META_MONITOR_TRANSFORM_FLIPPED_180,
|
||||
META_MONITOR_TRANSFORM_FLIPPED_270,
|
||||
} MetaMonitorTransform;
|
||||
|
||||
struct _MetaOutput
|
||||
{
|
||||
/* The CRTC driving this output, NULL if the output is not enabled */
|
||||
MetaCRTC *crtc;
|
||||
/* The low-level ID of this output, used to apply back configuration */
|
||||
glong winsys_id;
|
||||
glong output_id;
|
||||
char *name;
|
||||
char *vendor;
|
||||
char *product;
|
||||
@@ -124,7 +114,7 @@ struct _MetaCRTC
|
||||
glong crtc_id;
|
||||
MetaRectangle rect;
|
||||
MetaMonitorMode *current_mode;
|
||||
MetaMonitorTransform transform;
|
||||
enum wl_output_transform transform;
|
||||
unsigned int all_transforms;
|
||||
|
||||
/* Only used to build the logical configuration
|
||||
@@ -172,14 +162,14 @@ struct _MetaMonitorInfo
|
||||
gboolean in_fullscreen;
|
||||
|
||||
/* The primary or first output for this monitor, 0 if we can't figure out.
|
||||
It can be matched to a winsys_id of a MetaOutput.
|
||||
It can be matched to an output_id of a MetaOutput.
|
||||
|
||||
This is used as an opaque token on reconfiguration when switching from
|
||||
clone to extened, to decide on what output the windows should go next
|
||||
(it's an attempt to keep windows on the same monitor, and preferably on
|
||||
the primary one).
|
||||
*/
|
||||
glong winsys_id;
|
||||
glong output_id;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -195,7 +185,7 @@ struct _MetaCRTCInfo {
|
||||
MetaMonitorMode *mode;
|
||||
int x;
|
||||
int y;
|
||||
MetaMonitorTransform transform;
|
||||
enum wl_output_transform transform;
|
||||
GPtrArray *outputs;
|
||||
};
|
||||
|
||||
@@ -349,7 +339,7 @@ gboolean meta_monitor_manager_has_hotplug_mode_update (MetaMonitorMana
|
||||
/* Returns true if transform causes width and height to be inverted
|
||||
This is true for the odd transforms in the enum */
|
||||
static inline gboolean
|
||||
meta_monitor_transform_is_rotated (MetaMonitorTransform transform)
|
||||
meta_monitor_transform_is_rotated (enum wl_output_transform transform)
|
||||
{
|
||||
return (transform % 2);
|
||||
}
|
||||
|
@@ -40,6 +40,8 @@
|
||||
#include <meta/errors.h>
|
||||
#include "edid.h"
|
||||
|
||||
#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
|
||||
typedef struct {
|
||||
drmModeConnector *connector;
|
||||
|
||||
@@ -257,7 +259,7 @@ find_output_by_id (MetaOutput *outputs,
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
if (outputs[i].winsys_id == id)
|
||||
if (outputs[i].output_id == id)
|
||||
return &outputs[i];
|
||||
|
||||
return NULL;
|
||||
@@ -361,9 +363,9 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
meta_crtc->rect.width = crtc->width;
|
||||
meta_crtc->rect.height = crtc->height;
|
||||
meta_crtc->is_dirty = FALSE;
|
||||
meta_crtc->transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
meta_crtc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
/* FIXME: implement! */
|
||||
meta_crtc->all_transforms = 1 << META_MONITOR_TRANSFORM_NORMAL;
|
||||
meta_crtc->all_transforms = 1 << WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
|
||||
if (crtc->mode_valid)
|
||||
{
|
||||
@@ -406,7 +408,7 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
meta_output->driver_private = output_kms = g_slice_new0 (MetaOutputKms);
|
||||
meta_output->driver_notify = (GDestroyNotify)meta_output_destroy_notify;
|
||||
|
||||
meta_output->winsys_id = connector->connector_id;
|
||||
meta_output->output_id = connector->connector_id;
|
||||
meta_output->name = make_output_name (connector);
|
||||
meta_output->width_mm = connector->mmWidth;
|
||||
meta_output->height_mm = connector->mmHeight;
|
||||
@@ -489,7 +491,7 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
meta_output->crtc = NULL;
|
||||
|
||||
old_output = find_output_by_id (old_outputs, n_old_outputs,
|
||||
meta_output->winsys_id);
|
||||
meta_output->output_id);
|
||||
if (old_output)
|
||||
{
|
||||
meta_output->is_primary = old_output->is_primary;
|
||||
@@ -665,7 +667,7 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
|
||||
|
||||
if (output_kms->dpms_prop_id != 0)
|
||||
{
|
||||
int ok = drmModeConnectorSetProperty(manager_kms->fd, meta_output->winsys_id,
|
||||
int ok = drmModeConnectorSetProperty(manager_kms->fd, meta_output->output_id,
|
||||
output_kms->dpms_prop_id, state);
|
||||
|
||||
if (ok < 0)
|
||||
@@ -746,7 +748,7 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
{
|
||||
MetaOutput *output = g_ptr_array_index (crtc_info->outputs, j);
|
||||
|
||||
connectors[j] = output->winsys_id;
|
||||
connectors[j] = output->output_id;
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
|
@@ -151,15 +151,10 @@ handle_host_xevent (MetaBackend *backend,
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
gboolean bypass_clutter = FALSE;
|
||||
|
||||
XGetEventData (priv->xdisplay, &event->xcookie);
|
||||
|
||||
if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
|
||||
bypass_clutter = TRUE;
|
||||
|
||||
if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
|
||||
handle_alarm_notify (backend, event);
|
||||
|
||||
@@ -257,24 +252,6 @@ x_event_source_new (MetaBackend *backend)
|
||||
return source;
|
||||
}
|
||||
|
||||
static void
|
||||
take_touch_grab (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { META_VIRTUAL_CORE_POINTER_ID, sizeof (mask_bits), mask_bits };
|
||||
XIGrabModifiers mods = { XIAnyModifier, 0 };
|
||||
|
||||
XISetMask (mask.mask, XI_TouchBegin);
|
||||
XISetMask (mask.mask, XI_TouchUpdate);
|
||||
XISetMask (mask.mask, XI_TouchEnd);
|
||||
|
||||
XIGrabTouchBegin (priv->xdisplay, META_VIRTUAL_CORE_POINTER_ID,
|
||||
DefaultRootWindow (priv->xdisplay),
|
||||
False, &mask, 1, &mods);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_post_init (MetaBackend *backend)
|
||||
{
|
||||
@@ -312,8 +289,6 @@ meta_backend_x11_post_init (MetaBackend *backend)
|
||||
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
|
||||
}
|
||||
|
||||
take_touch_grab (backend);
|
||||
|
||||
META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend);
|
||||
}
|
||||
|
||||
|
@@ -42,7 +42,7 @@
|
||||
#include "edid.h"
|
||||
#include "meta-monitor-config.h"
|
||||
|
||||
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
|
||||
/* Look for DPI_FALLBACK in:
|
||||
* http://git.gnome.org/browse/gnome-settings-daemon/tree/plugins/xsettings/gsd-xsettings-manager.c
|
||||
@@ -67,31 +67,31 @@ struct _MetaMonitorManagerXrandrClass
|
||||
|
||||
G_DEFINE_TYPE (MetaMonitorManagerXrandr, meta_monitor_manager_xrandr, META_TYPE_MONITOR_MANAGER);
|
||||
|
||||
static MetaMonitorTransform
|
||||
meta_monitor_transform_from_xrandr (Rotation rotation)
|
||||
static enum wl_output_transform
|
||||
wl_transform_from_xrandr (Rotation rotation)
|
||||
{
|
||||
static const MetaMonitorTransform y_reflected_map[4] = {
|
||||
META_MONITOR_TRANSFORM_FLIPPED_180,
|
||||
META_MONITOR_TRANSFORM_FLIPPED_90,
|
||||
META_MONITOR_TRANSFORM_FLIPPED,
|
||||
META_MONITOR_TRANSFORM_FLIPPED_270
|
||||
static const enum wl_output_transform y_reflected_map[4] = {
|
||||
WL_OUTPUT_TRANSFORM_FLIPPED_180,
|
||||
WL_OUTPUT_TRANSFORM_FLIPPED_90,
|
||||
WL_OUTPUT_TRANSFORM_FLIPPED,
|
||||
WL_OUTPUT_TRANSFORM_FLIPPED_270
|
||||
};
|
||||
MetaMonitorTransform ret;
|
||||
enum wl_output_transform ret;
|
||||
|
||||
switch (rotation & 0x7F)
|
||||
{
|
||||
default:
|
||||
case RR_Rotate_0:
|
||||
ret = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
break;
|
||||
case RR_Rotate_90:
|
||||
ret = META_MONITOR_TRANSFORM_90;
|
||||
ret = WL_OUTPUT_TRANSFORM_90;
|
||||
break;
|
||||
case RR_Rotate_180:
|
||||
ret = META_MONITOR_TRANSFORM_180;
|
||||
ret = WL_OUTPUT_TRANSFORM_180;
|
||||
break;
|
||||
case RR_Rotate_270:
|
||||
ret = META_MONITOR_TRANSFORM_270;
|
||||
ret = WL_OUTPUT_TRANSFORM_270;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -105,35 +105,35 @@ meta_monitor_transform_from_xrandr (Rotation rotation)
|
||||
|
||||
#define ALL_ROTATIONS (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270)
|
||||
|
||||
static MetaMonitorTransform
|
||||
meta_monitor_transform_from_xrandr_all (Rotation rotation)
|
||||
static unsigned int
|
||||
wl_transform_from_xrandr_all (Rotation rotation)
|
||||
{
|
||||
unsigned ret;
|
||||
|
||||
/* Handle the common cases first (none or all) */
|
||||
if (rotation == 0 || rotation == RR_Rotate_0)
|
||||
return (1 << META_MONITOR_TRANSFORM_NORMAL);
|
||||
return (1 << WL_OUTPUT_TRANSFORM_NORMAL);
|
||||
|
||||
/* All rotations and one reflection -> all of them by composition */
|
||||
if ((rotation & ALL_ROTATIONS) &&
|
||||
((rotation & RR_Reflect_X) || (rotation & RR_Reflect_Y)))
|
||||
return ALL_TRANSFORMS;
|
||||
return ALL_WL_TRANSFORMS;
|
||||
|
||||
ret = 1 << META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret = 1 << WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
if (rotation & RR_Rotate_90)
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_90;
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_90;
|
||||
if (rotation & RR_Rotate_180)
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_180;
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_180;
|
||||
if (rotation & RR_Rotate_270)
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_270;
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_270;
|
||||
if (rotation & (RR_Rotate_0 | RR_Reflect_X))
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED;
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED;
|
||||
if (rotation & (RR_Rotate_90 | RR_Reflect_X))
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED_90;
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED_90;
|
||||
if (rotation & (RR_Rotate_180 | RR_Reflect_X))
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED_180;
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED_180;
|
||||
if (rotation & (RR_Rotate_270 | RR_Reflect_X))
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED_270;
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED_270;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -150,7 +150,7 @@ output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "_MUTTER_PRESENTATION_OUTPUT", False);
|
||||
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
(XID)output->output_id,
|
||||
atom,
|
||||
0, G_MAXLONG, False, False, XA_CARDINAL,
|
||||
&actual_type, &actual_format,
|
||||
@@ -186,7 +186,7 @@ output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
|
||||
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
(XID)output->output_id,
|
||||
atom,
|
||||
0, G_MAXLONG, False, False, XA_INTEGER,
|
||||
&actual_type, &actual_format,
|
||||
@@ -211,7 +211,7 @@ output_get_backlight_limits_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
|
||||
info = XRRQueryOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
(XID)output->output_id,
|
||||
atom);
|
||||
|
||||
if (info == NULL)
|
||||
@@ -278,25 +278,25 @@ get_edid_property (Display *dpy,
|
||||
|
||||
static GBytes *
|
||||
read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
XID winsys_id)
|
||||
XID output_id)
|
||||
{
|
||||
Atom edid_atom;
|
||||
guint8 *result;
|
||||
gsize len;
|
||||
|
||||
edid_atom = XInternAtom (manager_xrandr->xdisplay, "EDID", FALSE);
|
||||
result = get_edid_property (manager_xrandr->xdisplay, winsys_id, edid_atom, &len);
|
||||
result = get_edid_property (manager_xrandr->xdisplay, output_id, edid_atom, &len);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
edid_atom = XInternAtom (manager_xrandr->xdisplay, "EDID_DATA", FALSE);
|
||||
result = get_edid_property (manager_xrandr->xdisplay, winsys_id, edid_atom, &len);
|
||||
result = get_edid_property (manager_xrandr->xdisplay, output_id, edid_atom, &len);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
edid_atom = XInternAtom (manager_xrandr->xdisplay, "XFree86_DDC_EDID1_RAWDATA", FALSE);
|
||||
result = get_edid_property (manager_xrandr->xdisplay, winsys_id, edid_atom, &len);
|
||||
result = get_edid_property (manager_xrandr->xdisplay, output_id, edid_atom, &len);
|
||||
}
|
||||
|
||||
if (result)
|
||||
@@ -312,14 +312,14 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
|
||||
static gboolean
|
||||
output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
XID winsys_id)
|
||||
XID output_id)
|
||||
{
|
||||
Atom atom;
|
||||
XRRPropertyInfo *info;
|
||||
gboolean result = FALSE;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "hotplug_mode_update", False);
|
||||
info = XRRQueryOutputProperty (manager_xrandr->xdisplay, winsys_id,
|
||||
info = XRRQueryOutputProperty (manager_xrandr->xdisplay, output_id,
|
||||
atom);
|
||||
|
||||
if (info)
|
||||
@@ -434,8 +434,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
meta_crtc->rect.width = crtc->width;
|
||||
meta_crtc->rect.height = crtc->height;
|
||||
meta_crtc->is_dirty = FALSE;
|
||||
meta_crtc->transform = meta_monitor_transform_from_xrandr (crtc->rotation);
|
||||
meta_crtc->all_transforms = meta_monitor_transform_from_xrandr_all (crtc->rotations);
|
||||
meta_crtc->transform = wl_transform_from_xrandr (crtc->rotation);
|
||||
meta_crtc->all_transforms = wl_transform_from_xrandr_all (crtc->rotations);
|
||||
|
||||
for (j = 0; j < (unsigned)resources->nmode; j++)
|
||||
{
|
||||
@@ -467,10 +467,10 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
GBytes *edid;
|
||||
MonitorInfo *parsed_edid;
|
||||
|
||||
meta_output->winsys_id = resources->outputs[i];
|
||||
meta_output->output_id = resources->outputs[i];
|
||||
meta_output->name = g_strdup (output->name);
|
||||
|
||||
edid = read_output_edid (manager_xrandr, meta_output->winsys_id);
|
||||
edid = read_output_edid (manager_xrandr, meta_output->output_id);
|
||||
if (edid)
|
||||
{
|
||||
gsize len;
|
||||
@@ -504,7 +504,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
meta_output->height_mm = output->mm_height;
|
||||
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
meta_output->hotplug_mode_update =
|
||||
output_get_hotplug_mode_update (manager_xrandr, meta_output->winsys_id);
|
||||
output_get_hotplug_mode_update (manager_xrandr, meta_output->output_id);
|
||||
|
||||
meta_output->n_modes = output->nmode;
|
||||
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
|
||||
@@ -556,7 +556,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
meta_output->possible_clones[j] = GINT_TO_POINTER (output->clones[j]);
|
||||
}
|
||||
|
||||
meta_output->is_primary = ((XID)meta_output->winsys_id == primary_output);
|
||||
meta_output->is_primary = ((XID)meta_output->output_id == primary_output);
|
||||
meta_output->is_presentation = output_get_presentation_xrandr (manager_xrandr, meta_output);
|
||||
output_get_backlight_limits_xrandr (manager_xrandr, meta_output);
|
||||
|
||||
@@ -589,7 +589,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
|
||||
for (k = 0; k < manager->n_outputs; k++)
|
||||
{
|
||||
if (clone == (XID)manager->outputs[k].winsys_id)
|
||||
if (clone == (XID)manager->outputs[k].output_id)
|
||||
{
|
||||
meta_output->possible_clones[j] = &manager->outputs[k];
|
||||
break;
|
||||
@@ -605,7 +605,7 @@ meta_monitor_manager_xrandr_read_edid (MetaMonitorManager *manager,
|
||||
{
|
||||
MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
|
||||
|
||||
return read_output_edid (manager_xrandr, output->winsys_id);
|
||||
return read_output_edid (manager_xrandr, output->output_id);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -637,25 +637,25 @@ meta_monitor_manager_xrandr_set_power_save_mode (MetaMonitorManager *manager,
|
||||
}
|
||||
|
||||
static Rotation
|
||||
meta_monitor_transform_to_xrandr (MetaMonitorTransform transform)
|
||||
wl_transform_to_xrandr (enum wl_output_transform transform)
|
||||
{
|
||||
switch (transform)
|
||||
{
|
||||
case META_MONITOR_TRANSFORM_NORMAL:
|
||||
case WL_OUTPUT_TRANSFORM_NORMAL:
|
||||
return RR_Rotate_0;
|
||||
case META_MONITOR_TRANSFORM_90:
|
||||
case WL_OUTPUT_TRANSFORM_90:
|
||||
return RR_Rotate_90;
|
||||
case META_MONITOR_TRANSFORM_180:
|
||||
case WL_OUTPUT_TRANSFORM_180:
|
||||
return RR_Rotate_180;
|
||||
case META_MONITOR_TRANSFORM_270:
|
||||
case WL_OUTPUT_TRANSFORM_270:
|
||||
return RR_Rotate_270;
|
||||
case META_MONITOR_TRANSFORM_FLIPPED:
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
||||
return RR_Reflect_X | RR_Rotate_0;
|
||||
case META_MONITOR_TRANSFORM_FLIPPED_90:
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
||||
return RR_Reflect_X | RR_Rotate_90;
|
||||
case META_MONITOR_TRANSFORM_FLIPPED_180:
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
||||
return RR_Reflect_X | RR_Rotate_180;
|
||||
case META_MONITOR_TRANSFORM_FLIPPED_270:
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
||||
return RR_Reflect_X | RR_Rotate_270;
|
||||
}
|
||||
|
||||
@@ -672,7 +672,7 @@ output_set_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "_MUTTER_PRESENTATION_OUTPUT", False);
|
||||
XRRChangeOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
(XID)output->output_id,
|
||||
atom,
|
||||
XA_CARDINAL, 32, PropModeReplace,
|
||||
(unsigned char*) &value, 1);
|
||||
@@ -828,7 +828,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
output->crtc = crtc;
|
||||
new_controlled_mask |= 1UL << j;
|
||||
|
||||
outputs[j] = output->winsys_id;
|
||||
outputs[j] = output->output_id;
|
||||
}
|
||||
|
||||
if (crtc->current_mode == mode &&
|
||||
@@ -847,7 +847,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
manager_xrandr->time,
|
||||
crtc_info->x, crtc_info->y,
|
||||
(XID)mode->mode_id,
|
||||
meta_monitor_transform_to_xrandr (crtc_info->transform),
|
||||
wl_transform_to_xrandr (crtc_info->transform),
|
||||
outputs, n_outputs);
|
||||
|
||||
if (ok != Success)
|
||||
@@ -891,7 +891,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
{
|
||||
XRRSetOutputPrimary (manager_xrandr->xdisplay,
|
||||
DefaultRootWindow (manager_xrandr->xdisplay),
|
||||
(XID)output_info->output->winsys_id);
|
||||
(XID)output_info->output->output_id);
|
||||
}
|
||||
|
||||
output_set_presentation_xrandr (manager_xrandr,
|
||||
@@ -934,7 +934,7 @@ meta_monitor_manager_xrandr_change_backlight (MetaMonitorManager *manager,
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
|
||||
XRRChangeOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
(XID)output->output_id,
|
||||
atom,
|
||||
XA_INTEGER, 32, PropModeReplace,
|
||||
(unsigned char *) &hw_value, 1);
|
||||
|
@@ -148,6 +148,33 @@ process_damage (MetaCompositor *compositor,
|
||||
meta_window_actor_process_x11_damage (window_actor, event);
|
||||
}
|
||||
|
||||
static Window
|
||||
get_output_window (MetaCompositor *compositor)
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
|
||||
Window output;
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
|
||||
output = XCompositeGetOverlayWindow (xdisplay, DefaultRootWindow (xdisplay));
|
||||
|
||||
meta_core_add_old_event_mask (xdisplay, output, &mask);
|
||||
|
||||
XISetMask (mask.mask, XI_KeyPress);
|
||||
XISetMask (mask.mask, XI_KeyRelease);
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Enter);
|
||||
XISetMask (mask.mask, XI_Leave);
|
||||
XISetMask (mask.mask, XI_FocusIn);
|
||||
XISetMask (mask.mask, XI_FocusOut);
|
||||
XISetMask (mask.mask, XI_Motion);
|
||||
XISelectEvents (xdisplay, output, &mask, 1);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/* compat helper */
|
||||
static MetaCompositor *
|
||||
get_compositor_for_screen (MetaScreen *screen)
|
||||
@@ -467,12 +494,12 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
MetaWaylandCompositor *wayland_compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
compositor->stage = meta_stage_new ();
|
||||
clutter_actor_show (compositor->stage);
|
||||
|
||||
wayland_compositor->stage = compositor->stage;
|
||||
|
||||
meta_screen_get_size (screen, &width, &height);
|
||||
clutter_actor_set_size (compositor->stage, width, height);
|
||||
clutter_actor_show (compositor->stage);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -491,6 +518,8 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
|
||||
meta_core_add_old_event_mask (backend_xdisplay, xwin, &mask);
|
||||
|
||||
XISetMask (mask.mask, XI_KeyPress);
|
||||
XISetMask (mask.mask, XI_KeyRelease);
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
@@ -507,16 +536,10 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
}
|
||||
}
|
||||
|
||||
/* We use connect_after() here to accomodate code in GNOME Shell that,
|
||||
* when benchmarking drawing performance, connects to ::after-paint
|
||||
* and calls glFinish(). The timing information from that will be
|
||||
* more accurate if we hold off until that completes before we signal
|
||||
* apps to begin drawing the next frame. If there are no other
|
||||
* connections to ::after-paint, connect() vs. connect_after() doesn't
|
||||
* matter.
|
||||
*/
|
||||
g_signal_connect_after (CLUTTER_STAGE (compositor->stage), "after-paint",
|
||||
G_CALLBACK (after_stage_paint), compositor);
|
||||
clutter_stage_set_paint_callback (CLUTTER_STAGE (compositor->stage),
|
||||
after_stage_paint,
|
||||
compositor,
|
||||
NULL);
|
||||
|
||||
clutter_stage_set_sync_delay (CLUTTER_STAGE (compositor->stage), META_SYNC_DELAY);
|
||||
|
||||
@@ -535,8 +558,7 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
}
|
||||
else
|
||||
{
|
||||
compositor->output = screen->composite_overlay_window;
|
||||
|
||||
compositor->output = get_output_window (compositor);
|
||||
XReparentWindow (xdisplay, xwin, compositor->output, 0, 0);
|
||||
|
||||
meta_empty_stage_input_region (screen);
|
||||
@@ -741,6 +763,9 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
XEvent *event,
|
||||
MetaWindow *window)
|
||||
{
|
||||
if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
|
||||
return TRUE;
|
||||
|
||||
if (!meta_is_wayland_compositor () &&
|
||||
event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
|
||||
{
|
||||
|
@@ -109,7 +109,7 @@ meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor)
|
||||
}
|
||||
|
||||
static int
|
||||
get_output_scale (int winsys_id)
|
||||
get_output_scale (int output_id)
|
||||
{
|
||||
MetaMonitorManager *monitor_manager = meta_monitor_manager_get ();
|
||||
MetaOutput *outputs;
|
||||
@@ -120,7 +120,7 @@ get_output_scale (int winsys_id)
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
if (outputs[i].winsys_id == winsys_id)
|
||||
if (outputs[i].output_id == output_id)
|
||||
{
|
||||
output_scale = outputs[i].scale;
|
||||
break;
|
||||
@@ -150,7 +150,7 @@ meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor)
|
||||
|
||||
/* XXX: We do not handle x11 clients yet */
|
||||
if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11)
|
||||
output_scale = get_output_scale (window->monitor->winsys_id);
|
||||
output_scale = get_output_scale (window->monitor->output_id);
|
||||
|
||||
return (double)output_scale / (double)priv->surface->scale;
|
||||
}
|
||||
|
@@ -36,12 +36,6 @@
|
||||
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
|
||||
typedef enum {
|
||||
INITIALLY_FROZEN,
|
||||
DRAWING_FIRST_FRAME,
|
||||
EMITTED_FIRST_FRAME
|
||||
} FirstFrameState;
|
||||
|
||||
struct _MetaWindowActorPrivate
|
||||
{
|
||||
MetaWindow *window;
|
||||
@@ -110,7 +104,6 @@ struct _MetaWindowActorPrivate
|
||||
guint no_shadow : 1;
|
||||
|
||||
guint updates_frozen : 1;
|
||||
guint first_frame_state : 2; /* FirstFrameState */
|
||||
};
|
||||
|
||||
typedef struct _FrameData FrameData;
|
||||
@@ -122,14 +115,6 @@ struct _FrameData
|
||||
gint64 frame_drawn_time;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FIRST_FRAME,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_META_WINDOW = 1,
|
||||
@@ -196,31 +181,6 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
|
||||
actor_class->paint = meta_window_actor_paint;
|
||||
actor_class->get_paint_volume = meta_window_actor_get_paint_volume;
|
||||
|
||||
/**
|
||||
* MetaWindowActor::first-frame:
|
||||
* @actor: the #MetaWindowActor instance
|
||||
*
|
||||
* The ::first-frame signal will be emitted the first time a frame
|
||||
* of window contents has been drawn by the application and Mutter
|
||||
* has had the chance to drawn that frame to the screen. If the
|
||||
* window starts off initially hidden, obscured, or on on a
|
||||
* different workspace, the ::first-frame signal will be emitted
|
||||
* even though the user doesn't see the contents.
|
||||
*
|
||||
* MetaDisplay::window-created is a good place to connect to this
|
||||
* signal - at that point, the MetaWindowActor for the window
|
||||
* exists, but the window has reliably not yet been drawn.
|
||||
* Connecting to an existing window that has already been drawn to
|
||||
* the screen is not useful.
|
||||
*/
|
||||
signals[FIRST_FRAME] =
|
||||
g_signal_new ("first-frame",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
pspec = g_param_spec_object ("meta-window",
|
||||
"MetaWindow",
|
||||
"The displayed MetaWindow",
|
||||
@@ -346,9 +306,6 @@ meta_window_actor_thaw (MetaWindowActor *self)
|
||||
if (priv->freeze_count > 0)
|
||||
return;
|
||||
|
||||
if (priv->first_frame_state == INITIALLY_FROZEN)
|
||||
priv->first_frame_state = DRAWING_FIRST_FRAME;
|
||||
|
||||
if (priv->surface)
|
||||
meta_surface_actor_set_frozen (priv->surface, FALSE);
|
||||
|
||||
@@ -391,9 +348,6 @@ set_surface (MetaWindowActor *self,
|
||||
* frozen as well... */
|
||||
meta_surface_actor_set_frozen (priv->surface, priv->freeze_count > 0);
|
||||
|
||||
if (!is_frozen (self) && priv->first_frame_state == INITIALLY_FROZEN)
|
||||
priv->first_frame_state = DRAWING_FIRST_FRAME;
|
||||
|
||||
meta_window_actor_update_shape (self);
|
||||
}
|
||||
}
|
||||
@@ -899,7 +853,7 @@ queue_send_frame_messages_timeout (MetaWindowActor *self)
|
||||
outputs = meta_monitor_manager_get_outputs (monitor_manager, &n_outputs);
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
if (outputs[i].winsys_id == window->monitor->winsys_id && outputs[i].crtc)
|
||||
if (outputs[i].output_id == window->monitor->output_id && outputs[i].crtc)
|
||||
{
|
||||
refresh_rate = outputs[i].crtc->current_mode->refresh_rate;
|
||||
break;
|
||||
@@ -1374,11 +1328,6 @@ meta_window_actor_new (MetaWindow *window)
|
||||
|
||||
meta_window_actor_sync_updates_frozen (self);
|
||||
|
||||
if (is_frozen (self))
|
||||
priv->first_frame_state = INITIALLY_FROZEN;
|
||||
else
|
||||
priv->first_frame_state = DRAWING_FIRST_FRAME;
|
||||
|
||||
/* If a window doesn't start off with updates frozen, we should
|
||||
* we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn.
|
||||
*/
|
||||
@@ -1961,12 +1910,6 @@ meta_window_actor_post_paint (MetaWindowActor *self)
|
||||
do_send_frame_drawn (self, priv->frames->data);
|
||||
priv->needs_frame_drawn = FALSE;
|
||||
}
|
||||
|
||||
if (priv->first_frame_state == DRAWING_FIRST_FRAME)
|
||||
{
|
||||
priv->first_frame_state = EMITTED_FIRST_FRAME;
|
||||
g_signal_emit (self, signals[FIRST_FRAME], 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -495,5 +495,46 @@ meta_core_set_screen_cursor (Display *xdisplay,
|
||||
void
|
||||
meta_invalidate_default_icons (void)
|
||||
{
|
||||
/* XXX: Actually invalidate the icons when they're used. */
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
GSList *windows;
|
||||
GSList *l;
|
||||
|
||||
if (display == NULL)
|
||||
return; /* We can validly be called before the display is opened. */
|
||||
|
||||
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
|
||||
for (l = windows; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWindow *window = (MetaWindow*)l->data;
|
||||
|
||||
if (window->icon_cache.origin == USING_FALLBACK_ICON)
|
||||
{
|
||||
meta_icon_cache_free (&(window->icon_cache));
|
||||
meta_window_update_icon_now (window);
|
||||
}
|
||||
}
|
||||
|
||||
g_slist_free (windows);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_add_old_event_mask (Display *xdisplay,
|
||||
Window xwindow,
|
||||
XIEventMask *mask)
|
||||
{
|
||||
XIEventMask *prev;
|
||||
gint n_masks, i, j;
|
||||
|
||||
prev = XIGetSelectedEvents (xdisplay, xwindow, &n_masks);
|
||||
|
||||
for (i = 0; i < n_masks; i++)
|
||||
{
|
||||
if (prev[i].deviceid != XIAllMasterDevices)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < MIN (mask->mask_len, prev[i].mask_len); j++)
|
||||
mask->mask[j] |= prev[i].mask[j];
|
||||
}
|
||||
|
||||
XFree (prev);
|
||||
}
|
||||
|
@@ -169,4 +169,8 @@ void meta_core_set_screen_cursor (Display *xdisplay,
|
||||
|
||||
void meta_invalidate_default_icons (void);
|
||||
|
||||
void meta_core_add_old_event_mask (Display *xdisplay,
|
||||
Window xwindow,
|
||||
XIEventMask *mask);
|
||||
|
||||
#endif
|
||||
|
@@ -37,6 +37,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
|
||||
static void
|
||||
dialog_exited (GPid pid, int status, gpointer user_data)
|
||||
{
|
||||
|
@@ -35,7 +35,7 @@
|
||||
#include <meta/boxes.h>
|
||||
#include <meta/display.h>
|
||||
#include "keybindings-private.h"
|
||||
#include "meta-gesture-tracker-private.h"
|
||||
#include "gesture-tracker-private.h"
|
||||
#include <meta/prefs.h>
|
||||
#include <meta/barrier.h>
|
||||
#include <clutter/clutter.h>
|
||||
@@ -146,6 +146,8 @@ struct _MetaDisplay
|
||||
GHashTable *xids;
|
||||
GHashTable *wayland_windows;
|
||||
|
||||
int server_grab_count;
|
||||
|
||||
/* serials of leave/unmap events that may
|
||||
* correspond to an enter event we should
|
||||
* ignore
|
||||
@@ -312,6 +314,8 @@ struct _MetaDisplayClass
|
||||
gboolean meta_display_open (void);
|
||||
void meta_display_close (MetaDisplay *display,
|
||||
guint32 timestamp);
|
||||
void meta_display_grab (MetaDisplay *display);
|
||||
void meta_display_ungrab (MetaDisplay *display);
|
||||
|
||||
void meta_display_unmanage_windows_for_screen (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
@@ -441,16 +445,6 @@ void meta_display_sanity_check_timestamps (MetaDisplay *display,
|
||||
gboolean meta_display_timestamp_too_old (MetaDisplay *display,
|
||||
guint32 *timestamp);
|
||||
|
||||
void meta_display_remove_pending_pings_for_window (MetaDisplay *display,
|
||||
MetaWindow *window);
|
||||
|
||||
MetaGestureTracker * meta_display_get_gesture_tracker (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_show_restart_message (MetaDisplay *display,
|
||||
const char *message);
|
||||
gboolean meta_display_request_restart (MetaDisplay *display);
|
||||
|
||||
void meta_restart_init (void);
|
||||
void meta_restart_finish (void);
|
||||
|
||||
#endif
|
||||
|
@@ -52,6 +52,7 @@
|
||||
#include "meta-backend.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#include "compositor-private.h"
|
||||
|
||||
#ifdef HAVE_RANDR
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
@@ -71,6 +72,7 @@
|
||||
#include "x11/xprops.h"
|
||||
|
||||
#include "wayland/meta-xwayland-private.h"
|
||||
#include "meta-surface-actor-wayland.h"
|
||||
|
||||
/*
|
||||
* SECTION:pings
|
||||
@@ -117,8 +119,6 @@ enum
|
||||
WINDOW_MARKED_URGENT,
|
||||
GRAB_OP_BEGIN,
|
||||
GRAB_OP_END,
|
||||
SHOW_RESTART_MESSAGE,
|
||||
RESTART,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -148,6 +148,11 @@ static void update_window_grab_modifiers (MetaDisplay *display);
|
||||
static void prefs_changed_callback (MetaPreference pref,
|
||||
void *data);
|
||||
|
||||
static void meta_display_grab_window_touch (MetaDisplay *display,
|
||||
Window xwindow);
|
||||
static void meta_display_ungrab_window_touch (MetaDisplay *display,
|
||||
Window xwindow);
|
||||
|
||||
static void
|
||||
meta_display_get_property(GObject *object,
|
||||
guint prop_id,
|
||||
@@ -271,59 +276,6 @@ meta_display_class_init (MetaDisplayClass *klass)
|
||||
META_TYPE_WINDOW,
|
||||
META_TYPE_GRAB_OP);
|
||||
|
||||
/**
|
||||
* MetaDisplay::show-restart-message:
|
||||
* @display: the #MetaDisplay instance
|
||||
* @message: (allow-none): The message to display, or %NULL
|
||||
* to clear a previous restart message.
|
||||
*
|
||||
* The ::show-restart-message signal will be emitted to indicate
|
||||
* that the compositor should show a message during restart. This is
|
||||
* emitted when meta_restart() is called, either by Mutter
|
||||
* internally or by the embedding compositor. The message should be
|
||||
* immediately added to the Clutter stage in its final form -
|
||||
* ::restart will be emitted to exit the application and leave the
|
||||
* stage contents frozen as soon as the the stage is painted again.
|
||||
*
|
||||
* On case of failure to restart, this signal will be emitted again
|
||||
* with %NULL for @message.
|
||||
*
|
||||
* Returns: %TRUE means the message was added to the stage; %FALSE
|
||||
* indicates that the compositor did not show the message.
|
||||
*/
|
||||
display_signals[SHOW_RESTART_MESSAGE] =
|
||||
g_signal_new ("show-restart-message",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
g_signal_accumulator_true_handled,
|
||||
NULL, NULL,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
G_TYPE_STRING);
|
||||
|
||||
/**
|
||||
* MetaDisplay::restart:
|
||||
* @display: the #MetaDisplay instance
|
||||
*
|
||||
* The ::restart signal is emitted to indicate that compositor
|
||||
* should reexec the process. This is
|
||||
* emitted when meta_restart() is called, either by Mutter
|
||||
* internally or by the embedding compositor. See also
|
||||
* ::show-restart-message.
|
||||
*
|
||||
* Returns: %FALSE to indicate that the compositor could not
|
||||
* be restarted. When the compositor is restarted, the signal
|
||||
* should not return.
|
||||
*/
|
||||
display_signals[RESTART] =
|
||||
g_signal_new ("restart",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
g_signal_accumulator_true_handled,
|
||||
NULL, NULL,
|
||||
G_TYPE_BOOLEAN, 0);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_FOCUS_WINDOW,
|
||||
g_param_spec_object ("focus-window",
|
||||
@@ -350,9 +302,16 @@ ping_data_free (MetaPingData *ping_data)
|
||||
g_free (ping_data);
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_remove_pending_pings_for_window (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
/**
|
||||
* remove_pending_pings_for_window:
|
||||
* @display: The display the window appears on
|
||||
* @xwindow: The X ID of the window whose pings we should remove
|
||||
*
|
||||
* Frees every pending ping structure for the given X window on the
|
||||
* given display. This means that we also destroy the timeouts.
|
||||
*/
|
||||
static void
|
||||
remove_pending_pings_for_window (MetaDisplay *display, Window xwindow)
|
||||
{
|
||||
GSList *tmp;
|
||||
GSList *dead;
|
||||
@@ -365,7 +324,7 @@ meta_display_remove_pending_pings_for_window (MetaDisplay *display,
|
||||
{
|
||||
MetaPingData *ping_data = tmp->data;
|
||||
|
||||
if (ping_data->window == window)
|
||||
if (ping_data->window->xwindow == xwindow)
|
||||
dead = g_slist_prepend (dead, ping_data);
|
||||
}
|
||||
|
||||
@@ -496,7 +455,6 @@ gesture_tracker_state_changed (MetaGestureTracker *tracker,
|
||||
gboolean
|
||||
meta_display_open (void)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
Display *xdisplay;
|
||||
MetaScreen *screen;
|
||||
int i;
|
||||
@@ -528,223 +486,224 @@ meta_display_open (void)
|
||||
XSynchronize (xdisplay, True);
|
||||
|
||||
g_assert (the_display == NULL);
|
||||
display = the_display = g_object_new (META_TYPE_DISPLAY, NULL);
|
||||
the_display = g_object_new (META_TYPE_DISPLAY, NULL);
|
||||
|
||||
display->closing = 0;
|
||||
the_display->closing = 0;
|
||||
|
||||
/* here we use XDisplayName which is what the user
|
||||
* probably put in, vs. DisplayString(display) which is
|
||||
* canonicalized by XOpenDisplay()
|
||||
*/
|
||||
display->name = g_strdup (XDisplayName (NULL));
|
||||
display->xdisplay = xdisplay;
|
||||
display->display_opening = TRUE;
|
||||
the_display->name = g_strdup (XDisplayName (NULL));
|
||||
the_display->xdisplay = xdisplay;
|
||||
the_display->server_grab_count = 0;
|
||||
the_display->display_opening = TRUE;
|
||||
|
||||
display->pending_pings = NULL;
|
||||
display->autoraise_timeout_id = 0;
|
||||
display->autoraise_window = NULL;
|
||||
display->focus_window = NULL;
|
||||
display->focus_serial = 0;
|
||||
display->server_focus_window = None;
|
||||
display->server_focus_serial = 0;
|
||||
the_display->pending_pings = NULL;
|
||||
the_display->autoraise_timeout_id = 0;
|
||||
the_display->autoraise_window = NULL;
|
||||
the_display->focus_window = NULL;
|
||||
the_display->focus_serial = 0;
|
||||
the_display->server_focus_window = None;
|
||||
the_display->server_focus_serial = 0;
|
||||
|
||||
display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */
|
||||
display->allow_terminal_deactivation = TRUE; /* Only relevant for when a
|
||||
the_display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */
|
||||
the_display->allow_terminal_deactivation = TRUE; /* Only relevant for when a
|
||||
terminal has the focus */
|
||||
|
||||
meta_bell_init (display);
|
||||
meta_bell_init (the_display);
|
||||
|
||||
meta_display_init_keys (display);
|
||||
meta_display_init_keys (the_display);
|
||||
|
||||
update_window_grab_modifiers (display);
|
||||
update_window_grab_modifiers (the_display);
|
||||
|
||||
meta_prefs_add_listener (prefs_changed_callback, display);
|
||||
meta_prefs_add_listener (prefs_changed_callback, the_display);
|
||||
|
||||
meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names));
|
||||
XInternAtoms (display->xdisplay, atom_names, G_N_ELEMENTS (atom_names),
|
||||
XInternAtoms (the_display->xdisplay, atom_names, G_N_ELEMENTS (atom_names),
|
||||
False, atoms);
|
||||
{
|
||||
int i = 0;
|
||||
#define item(x) display->atom_##x = atoms[i++];
|
||||
#define item(x) the_display->atom_##x = atoms[i++];
|
||||
#include <meta/atomnames.h>
|
||||
#undef item
|
||||
}
|
||||
|
||||
display->prop_hooks = NULL;
|
||||
meta_display_init_window_prop_hooks (display);
|
||||
display->group_prop_hooks = NULL;
|
||||
meta_display_init_group_prop_hooks (display);
|
||||
the_display->prop_hooks = NULL;
|
||||
meta_display_init_window_prop_hooks (the_display);
|
||||
the_display->group_prop_hooks = NULL;
|
||||
meta_display_init_group_prop_hooks (the_display);
|
||||
|
||||
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
|
||||
* created in screen_new
|
||||
*/
|
||||
display->leader_window = None;
|
||||
display->timestamp_pinging_window = None;
|
||||
the_display->leader_window = None;
|
||||
the_display->timestamp_pinging_window = None;
|
||||
|
||||
display->monitor_cache_invalidated = TRUE;
|
||||
the_display->monitor_cache_invalidated = TRUE;
|
||||
|
||||
display->groups_by_leader = NULL;
|
||||
the_display->groups_by_leader = NULL;
|
||||
|
||||
display->screen = NULL;
|
||||
the_display->screen = NULL;
|
||||
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
display->sn_display = sn_display_new (display->xdisplay,
|
||||
the_display->sn_display = sn_display_new (the_display->xdisplay,
|
||||
sn_error_trap_push,
|
||||
sn_error_trap_pop);
|
||||
#endif
|
||||
|
||||
/* Get events */
|
||||
meta_display_init_events (display);
|
||||
meta_display_init_events (the_display);
|
||||
|
||||
display->xids = g_hash_table_new (meta_unsigned_long_hash,
|
||||
the_display->xids = g_hash_table_new (meta_unsigned_long_hash,
|
||||
meta_unsigned_long_equal);
|
||||
display->wayland_windows = g_hash_table_new (NULL, NULL);
|
||||
the_display->wayland_windows = g_hash_table_new (NULL, NULL);
|
||||
|
||||
i = 0;
|
||||
while (i < N_IGNORED_CROSSING_SERIALS)
|
||||
{
|
||||
display->ignored_crossing_serials[i] = 0;
|
||||
the_display->ignored_crossing_serials[i] = 0;
|
||||
++i;
|
||||
}
|
||||
display->ungrab_should_not_cause_focus_window = None;
|
||||
the_display->ungrab_should_not_cause_focus_window = None;
|
||||
|
||||
display->current_time = CurrentTime;
|
||||
display->sentinel_counter = 0;
|
||||
the_display->current_time = CurrentTime;
|
||||
the_display->sentinel_counter = 0;
|
||||
|
||||
display->grab_resize_timeout_id = 0;
|
||||
display->grab_have_keyboard = FALSE;
|
||||
the_display->grab_resize_timeout_id = 0;
|
||||
the_display->grab_have_keyboard = FALSE;
|
||||
|
||||
#ifdef HAVE_XKB
|
||||
display->last_bell_time = 0;
|
||||
the_display->last_bell_time = 0;
|
||||
#endif
|
||||
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
display->grab_window = NULL;
|
||||
display->grab_tile_mode = META_TILE_NONE;
|
||||
display->grab_tile_monitor_number = -1;
|
||||
the_display->grab_op = META_GRAB_OP_NONE;
|
||||
the_display->grab_window = NULL;
|
||||
the_display->grab_tile_mode = META_TILE_NONE;
|
||||
the_display->grab_tile_monitor_number = -1;
|
||||
|
||||
display->grab_edge_resistance_data = NULL;
|
||||
the_display->grab_edge_resistance_data = NULL;
|
||||
|
||||
{
|
||||
int major, minor;
|
||||
|
||||
display->have_xsync = FALSE;
|
||||
the_display->have_xsync = FALSE;
|
||||
|
||||
display->xsync_error_base = 0;
|
||||
display->xsync_event_base = 0;
|
||||
the_display->xsync_error_base = 0;
|
||||
the_display->xsync_event_base = 0;
|
||||
|
||||
/* I don't think we really have to fill these in */
|
||||
major = SYNC_MAJOR_VERSION;
|
||||
minor = SYNC_MINOR_VERSION;
|
||||
|
||||
if (!XSyncQueryExtension (display->xdisplay,
|
||||
&display->xsync_event_base,
|
||||
&display->xsync_error_base) ||
|
||||
!XSyncInitialize (display->xdisplay,
|
||||
if (!XSyncQueryExtension (the_display->xdisplay,
|
||||
&the_display->xsync_event_base,
|
||||
&the_display->xsync_error_base) ||
|
||||
!XSyncInitialize (the_display->xdisplay,
|
||||
&major, &minor))
|
||||
{
|
||||
display->xsync_error_base = 0;
|
||||
display->xsync_event_base = 0;
|
||||
the_display->xsync_error_base = 0;
|
||||
the_display->xsync_event_base = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
display->have_xsync = TRUE;
|
||||
XSyncSetPriority (display->xdisplay, None, 10);
|
||||
the_display->have_xsync = TRUE;
|
||||
XSyncSetPriority (the_display->xdisplay, None, 10);
|
||||
}
|
||||
|
||||
meta_verbose ("Attempted to init Xsync, found version %d.%d error base %d event base %d\n",
|
||||
major, minor,
|
||||
display->xsync_error_base,
|
||||
display->xsync_event_base);
|
||||
the_display->xsync_error_base,
|
||||
the_display->xsync_event_base);
|
||||
}
|
||||
|
||||
{
|
||||
display->have_shape = FALSE;
|
||||
the_display->have_shape = FALSE;
|
||||
|
||||
display->shape_error_base = 0;
|
||||
display->shape_event_base = 0;
|
||||
the_display->shape_error_base = 0;
|
||||
the_display->shape_event_base = 0;
|
||||
|
||||
if (!XShapeQueryExtension (display->xdisplay,
|
||||
&display->shape_event_base,
|
||||
&display->shape_error_base))
|
||||
if (!XShapeQueryExtension (the_display->xdisplay,
|
||||
&the_display->shape_event_base,
|
||||
&the_display->shape_error_base))
|
||||
{
|
||||
display->shape_error_base = 0;
|
||||
display->shape_event_base = 0;
|
||||
the_display->shape_error_base = 0;
|
||||
the_display->shape_event_base = 0;
|
||||
}
|
||||
else
|
||||
display->have_shape = TRUE;
|
||||
the_display->have_shape = TRUE;
|
||||
|
||||
meta_verbose ("Attempted to init Shape, found error base %d event base %d\n",
|
||||
display->shape_error_base,
|
||||
display->shape_event_base);
|
||||
the_display->shape_error_base,
|
||||
the_display->shape_event_base);
|
||||
}
|
||||
|
||||
{
|
||||
display->have_composite = FALSE;
|
||||
the_display->have_composite = FALSE;
|
||||
|
||||
display->composite_error_base = 0;
|
||||
display->composite_event_base = 0;
|
||||
the_display->composite_error_base = 0;
|
||||
the_display->composite_event_base = 0;
|
||||
|
||||
if (!XCompositeQueryExtension (display->xdisplay,
|
||||
&display->composite_event_base,
|
||||
&display->composite_error_base))
|
||||
if (!XCompositeQueryExtension (the_display->xdisplay,
|
||||
&the_display->composite_event_base,
|
||||
&the_display->composite_error_base))
|
||||
{
|
||||
display->composite_error_base = 0;
|
||||
display->composite_event_base = 0;
|
||||
the_display->composite_error_base = 0;
|
||||
the_display->composite_event_base = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
display->composite_major_version = 0;
|
||||
display->composite_minor_version = 0;
|
||||
if (XCompositeQueryVersion (display->xdisplay,
|
||||
&display->composite_major_version,
|
||||
&display->composite_minor_version))
|
||||
the_display->composite_major_version = 0;
|
||||
the_display->composite_minor_version = 0;
|
||||
if (XCompositeQueryVersion (the_display->xdisplay,
|
||||
&the_display->composite_major_version,
|
||||
&the_display->composite_minor_version))
|
||||
{
|
||||
display->have_composite = TRUE;
|
||||
the_display->have_composite = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
display->composite_major_version = 0;
|
||||
display->composite_minor_version = 0;
|
||||
the_display->composite_major_version = 0;
|
||||
the_display->composite_minor_version = 0;
|
||||
}
|
||||
}
|
||||
|
||||
meta_verbose ("Attempted to init Composite, found error base %d event base %d "
|
||||
"extn ver %d %d\n",
|
||||
display->composite_error_base,
|
||||
display->composite_event_base,
|
||||
display->composite_major_version,
|
||||
display->composite_minor_version);
|
||||
the_display->composite_error_base,
|
||||
the_display->composite_event_base,
|
||||
the_display->composite_major_version,
|
||||
the_display->composite_minor_version);
|
||||
|
||||
display->have_damage = FALSE;
|
||||
the_display->have_damage = FALSE;
|
||||
|
||||
display->damage_error_base = 0;
|
||||
display->damage_event_base = 0;
|
||||
the_display->damage_error_base = 0;
|
||||
the_display->damage_event_base = 0;
|
||||
|
||||
if (!XDamageQueryExtension (display->xdisplay,
|
||||
&display->damage_event_base,
|
||||
&display->damage_error_base))
|
||||
if (!XDamageQueryExtension (the_display->xdisplay,
|
||||
&the_display->damage_event_base,
|
||||
&the_display->damage_error_base))
|
||||
{
|
||||
display->damage_error_base = 0;
|
||||
display->damage_event_base = 0;
|
||||
the_display->damage_error_base = 0;
|
||||
the_display->damage_event_base = 0;
|
||||
}
|
||||
else
|
||||
display->have_damage = TRUE;
|
||||
the_display->have_damage = TRUE;
|
||||
|
||||
meta_verbose ("Attempted to init Damage, found error base %d event base %d\n",
|
||||
display->damage_error_base,
|
||||
display->damage_event_base);
|
||||
the_display->damage_error_base,
|
||||
the_display->damage_event_base);
|
||||
|
||||
display->xfixes_error_base = 0;
|
||||
display->xfixes_event_base = 0;
|
||||
the_display->xfixes_error_base = 0;
|
||||
the_display->xfixes_event_base = 0;
|
||||
|
||||
if (XFixesQueryExtension (display->xdisplay,
|
||||
&display->xfixes_event_base,
|
||||
&display->xfixes_error_base))
|
||||
if (XFixesQueryExtension (the_display->xdisplay,
|
||||
&the_display->xfixes_event_base,
|
||||
&the_display->xfixes_error_base))
|
||||
{
|
||||
int xfixes_major, xfixes_minor;
|
||||
|
||||
XFixesQueryVersion (display->xdisplay, &xfixes_major, &xfixes_minor);
|
||||
XFixesQueryVersion (the_display->xdisplay, &xfixes_major, &xfixes_minor);
|
||||
|
||||
if (xfixes_major * 100 + xfixes_minor < 500)
|
||||
meta_fatal ("Mutter requires XFixes 5.0");
|
||||
@@ -755,21 +714,21 @@ meta_display_open (void)
|
||||
}
|
||||
|
||||
meta_verbose ("Attempted to init XFixes, found error base %d event base %d\n",
|
||||
display->xfixes_error_base,
|
||||
display->xfixes_event_base);
|
||||
the_display->xfixes_error_base,
|
||||
the_display->xfixes_event_base);
|
||||
}
|
||||
|
||||
{
|
||||
int major = 2, minor = 3;
|
||||
gboolean has_xi = FALSE;
|
||||
|
||||
if (XQueryExtension (display->xdisplay,
|
||||
if (XQueryExtension (the_display->xdisplay,
|
||||
"XInputExtension",
|
||||
&display->xinput_opcode,
|
||||
&display->xinput_error_base,
|
||||
&display->xinput_event_base))
|
||||
&the_display->xinput_opcode,
|
||||
&the_display->xinput_error_base,
|
||||
&the_display->xinput_event_base))
|
||||
{
|
||||
if (XIQueryVersion (display->xdisplay, &major, &minor) == Success)
|
||||
if (XIQueryVersion (the_display->xdisplay, &major, &minor) == Success)
|
||||
{
|
||||
int version = (major * 10) + minor;
|
||||
if (version >= 22)
|
||||
@@ -777,7 +736,7 @@ meta_display_open (void)
|
||||
|
||||
#ifdef HAVE_XI23
|
||||
if (version >= 23)
|
||||
display->have_xinput_23 = TRUE;
|
||||
the_display->have_xinput_23 = TRUE;
|
||||
#endif /* HAVE_XI23 */
|
||||
}
|
||||
}
|
||||
@@ -801,35 +760,35 @@ meta_display_open (void)
|
||||
* this window, so we can't rely on it still being set later. See bug
|
||||
* 354213 for details.
|
||||
*/
|
||||
display->leader_window =
|
||||
meta_create_offscreen_window (display->xdisplay,
|
||||
DefaultRootWindow (display->xdisplay),
|
||||
the_display->leader_window =
|
||||
meta_create_offscreen_window (the_display->xdisplay,
|
||||
DefaultRootWindow (the_display->xdisplay),
|
||||
PropertyChangeMask);
|
||||
|
||||
meta_prop_set_utf8_string_hint (display,
|
||||
display->leader_window,
|
||||
display->atom__NET_WM_NAME,
|
||||
meta_prop_set_utf8_string_hint (the_display,
|
||||
the_display->leader_window,
|
||||
the_display->atom__NET_WM_NAME,
|
||||
net_wm_name);
|
||||
|
||||
meta_prop_set_utf8_string_hint (display,
|
||||
display->leader_window,
|
||||
display->atom__GNOME_WM_KEYBINDINGS,
|
||||
meta_prop_set_utf8_string_hint (the_display,
|
||||
the_display->leader_window,
|
||||
the_display->atom__GNOME_WM_KEYBINDINGS,
|
||||
gnome_wm_keybindings);
|
||||
|
||||
meta_prop_set_utf8_string_hint (display,
|
||||
display->leader_window,
|
||||
display->atom__MUTTER_VERSION,
|
||||
meta_prop_set_utf8_string_hint (the_display,
|
||||
the_display->leader_window,
|
||||
the_display->atom__MUTTER_VERSION,
|
||||
VERSION);
|
||||
|
||||
data[0] = display->leader_window;
|
||||
XChangeProperty (display->xdisplay,
|
||||
display->leader_window,
|
||||
display->atom__NET_SUPPORTING_WM_CHECK,
|
||||
data[0] = the_display->leader_window;
|
||||
XChangeProperty (the_display->xdisplay,
|
||||
the_display->leader_window,
|
||||
the_display->atom__NET_SUPPORTING_WM_CHECK,
|
||||
XA_WINDOW,
|
||||
32, PropModeReplace, (guchar*) data, 1);
|
||||
|
||||
XWindowEvent (display->xdisplay,
|
||||
display->leader_window,
|
||||
XWindowEvent (the_display->xdisplay,
|
||||
the_display->leader_window,
|
||||
PropertyChangeMask,
|
||||
&event);
|
||||
|
||||
@@ -838,51 +797,52 @@ meta_display_open (void)
|
||||
/* Make it painfully clear that we can't rely on PropertyNotify events on
|
||||
* this window, as per bug 354213.
|
||||
*/
|
||||
XSelectInput(display->xdisplay,
|
||||
display->leader_window,
|
||||
XSelectInput(the_display->xdisplay,
|
||||
the_display->leader_window,
|
||||
NoEventMask);
|
||||
}
|
||||
|
||||
/* Make a little window used only for pinging the server for timestamps; note
|
||||
* that meta_create_offscreen_window already selects for PropertyChangeMask.
|
||||
*/
|
||||
display->timestamp_pinging_window =
|
||||
meta_create_offscreen_window (display->xdisplay,
|
||||
DefaultRootWindow (display->xdisplay),
|
||||
the_display->timestamp_pinging_window =
|
||||
meta_create_offscreen_window (the_display->xdisplay,
|
||||
DefaultRootWindow (the_display->xdisplay),
|
||||
PropertyChangeMask);
|
||||
|
||||
display->last_focus_time = timestamp;
|
||||
display->last_user_time = timestamp;
|
||||
display->compositor = NULL;
|
||||
the_display->last_focus_time = timestamp;
|
||||
the_display->last_user_time = timestamp;
|
||||
the_display->compositor = NULL;
|
||||
|
||||
/* Mutter used to manage all X screens of the display in a single process, but
|
||||
* now it always manages exactly one screen as specified by the DISPLAY
|
||||
* environment variable.
|
||||
*/
|
||||
i = meta_ui_get_screen_number ();
|
||||
screen = meta_screen_new (display, i, timestamp);
|
||||
screen = meta_screen_new (the_display, i, timestamp);
|
||||
|
||||
if (!screen)
|
||||
{
|
||||
/* This would typically happen because all the screens already
|
||||
* have window managers.
|
||||
*/
|
||||
meta_display_close (display, timestamp);
|
||||
meta_display_close (the_display, timestamp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
display->screen = screen;
|
||||
the_display->screen = screen;
|
||||
|
||||
enable_compositor (the_display);
|
||||
|
||||
meta_screen_init_workspaces (screen);
|
||||
|
||||
enable_compositor (display);
|
||||
|
||||
meta_screen_create_guard_window (screen);
|
||||
|
||||
/* Set up touch support */
|
||||
display->gesture_tracker = meta_gesture_tracker_new ();
|
||||
g_signal_connect (display->gesture_tracker, "state-changed",
|
||||
G_CALLBACK (gesture_tracker_state_changed), display);
|
||||
the_display->gesture_tracker = meta_gesture_tracker_new (0);
|
||||
g_signal_connect (the_display->gesture_tracker, "state-changed",
|
||||
G_CALLBACK (gesture_tracker_state_changed), the_display);
|
||||
meta_display_grab_window_touch (the_display,
|
||||
DefaultRootWindow (the_display->xdisplay));
|
||||
|
||||
/* We know that if mutter is running as a Wayland compositor,
|
||||
* we start out with no windows.
|
||||
@@ -895,12 +855,12 @@ meta_display_open (void)
|
||||
int ret_to;
|
||||
|
||||
/* kinda bogus because GetInputFocus has no possible errors */
|
||||
meta_error_trap_push (display);
|
||||
meta_error_trap_push (the_display);
|
||||
|
||||
/* FIXME: This is totally broken; see comment 9 of bug 88194 about this */
|
||||
focus = None;
|
||||
ret_to = RevertToPointerRoot;
|
||||
XGetInputFocus (display->xdisplay, &focus, &ret_to);
|
||||
XGetInputFocus (the_display->xdisplay, &focus, &ret_to);
|
||||
|
||||
/* Force a new FocusIn (does this work?) */
|
||||
|
||||
@@ -909,29 +869,29 @@ meta_display_open (void)
|
||||
*/
|
||||
if (focus == None || focus == PointerRoot)
|
||||
/* Just focus the no_focus_window on the first screen */
|
||||
meta_display_focus_the_no_focus_window (display,
|
||||
display->screen,
|
||||
meta_display_focus_the_no_focus_window (the_display,
|
||||
the_display->screen,
|
||||
timestamp);
|
||||
else
|
||||
{
|
||||
MetaWindow * window;
|
||||
window = meta_display_lookup_x_window (display, focus);
|
||||
window = meta_display_lookup_x_window (the_display, focus);
|
||||
if (window)
|
||||
meta_display_set_input_focus_window (display, window, FALSE, timestamp);
|
||||
meta_display_set_input_focus_window (the_display, window, FALSE, timestamp);
|
||||
else
|
||||
/* Just focus the no_focus_window on the first screen */
|
||||
meta_display_focus_the_no_focus_window (display,
|
||||
display->screen,
|
||||
meta_display_focus_the_no_focus_window (the_display,
|
||||
the_display->screen,
|
||||
timestamp);
|
||||
}
|
||||
|
||||
meta_error_trap_pop (display);
|
||||
meta_error_trap_pop (the_display);
|
||||
}
|
||||
|
||||
meta_idle_monitor_init_dbus ();
|
||||
|
||||
/* Done opening new display */
|
||||
display->display_opening = FALSE;
|
||||
the_display->display_opening = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1040,7 +1000,6 @@ meta_display_close (MetaDisplay *display,
|
||||
guint32 timestamp)
|
||||
{
|
||||
g_assert (display != NULL);
|
||||
g_assert (display == the_display);
|
||||
|
||||
if (display->closing != 0)
|
||||
{
|
||||
@@ -1054,6 +1013,8 @@ meta_display_close (MetaDisplay *display,
|
||||
|
||||
meta_display_remove_autoraise_callback (display);
|
||||
|
||||
meta_display_ungrab_window_touch (display,
|
||||
DefaultRootWindow (display->xdisplay));
|
||||
g_clear_object (&display->gesture_tracker);
|
||||
|
||||
if (display->focus_timeout_id)
|
||||
@@ -1100,6 +1061,50 @@ meta_display_close (MetaDisplay *display,
|
||||
meta_quit (META_EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* Grab/ungrab routines taken from fvwm.
|
||||
* Calling this function will cause X to ignore all other clients until
|
||||
* you ungrab. This may not be quite as bad as it sounds, yet there is
|
||||
* agreement that avoiding server grabs except when they are clearly needed
|
||||
* is a good thing.
|
||||
*
|
||||
* If you do use such grabs, please clearly explain the necessity for their
|
||||
* usage in a comment. Try to keep their scope extremely limited. In
|
||||
* particular, try to avoid emitting any signals or notifications while
|
||||
* a grab is active (if the signal receiver tries to block on an X request
|
||||
* from another client at this point, you will have a deadlock).
|
||||
*/
|
||||
void
|
||||
meta_display_grab (MetaDisplay *display)
|
||||
{
|
||||
if (display->server_grab_count == 0)
|
||||
{
|
||||
XGrabServer (display->xdisplay);
|
||||
}
|
||||
display->server_grab_count += 1;
|
||||
meta_verbose ("Grabbing display, grab count now %d\n",
|
||||
display->server_grab_count);
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_ungrab (MetaDisplay *display)
|
||||
{
|
||||
if (display->server_grab_count == 0)
|
||||
meta_bug ("Ungrabbed non-grabbed server\n");
|
||||
|
||||
display->server_grab_count -= 1;
|
||||
if (display->server_grab_count == 0)
|
||||
{
|
||||
/* FIXME we want to purge all pending "queued" stuff
|
||||
* at this point, such as window hide/show
|
||||
*/
|
||||
XUngrabServer (display->xdisplay);
|
||||
XFlush (display->xdisplay);
|
||||
}
|
||||
|
||||
meta_verbose ("Ungrabbing display, grab count now %d\n",
|
||||
display->server_grab_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_for_x_display:
|
||||
* @xdisplay: An X display
|
||||
@@ -1534,7 +1539,7 @@ request_xserver_input_focus_change (MetaDisplay *display,
|
||||
* we know which is which by making two requests that the server will
|
||||
* process at the same time.
|
||||
*/
|
||||
XGrabServer (display->xdisplay);
|
||||
meta_display_grab (display);
|
||||
|
||||
serial = XNextRequest (display->xdisplay);
|
||||
|
||||
@@ -1547,8 +1552,7 @@ request_xserver_input_focus_change (MetaDisplay *display,
|
||||
display->atom__MUTTER_FOCUS_SET,
|
||||
XA_STRING, 8, PropModeAppend, NULL, 0);
|
||||
|
||||
XUngrabServer (display->xdisplay);
|
||||
XFlush (display->xdisplay);
|
||||
meta_display_ungrab (display);
|
||||
|
||||
meta_display_update_focus_window (display,
|
||||
meta_window,
|
||||
@@ -1588,6 +1592,9 @@ meta_display_unregister_x_window (MetaDisplay *display,
|
||||
g_return_if_fail (g_hash_table_lookup (display->xids, &xwindow) != NULL);
|
||||
|
||||
g_hash_table_remove (display->xids, &xwindow);
|
||||
|
||||
/* Remove any pending pings */
|
||||
remove_pending_pings_for_window (display, xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1863,19 +1870,18 @@ void
|
||||
meta_display_end_grab_op (MetaDisplay *display,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *grab_window = display->grab_window;
|
||||
MetaGrabOp grab_op = display->grab_op;
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Ending grab op %u at time %u\n", grab_op, timestamp);
|
||||
"Ending grab op %u at time %u\n", display->grab_op, timestamp);
|
||||
|
||||
if (display->grab_op == META_GRAB_OP_NONE)
|
||||
return;
|
||||
|
||||
g_signal_emit (display, display_signals[GRAB_OP_END], 0,
|
||||
display->screen, grab_window, grab_op);
|
||||
display->screen, display->grab_window, display->grab_op);
|
||||
|
||||
if (meta_grab_op_is_moving_or_resizing (grab_op))
|
||||
meta_window_grab_op_ended (display->grab_window, display->grab_op);
|
||||
|
||||
if (meta_grab_op_is_moving_or_resizing (display->grab_op))
|
||||
{
|
||||
/* Clear out the edge cache */
|
||||
meta_display_cleanup_edges (display);
|
||||
@@ -1901,7 +1907,7 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Ungrabbing all keys timestamp %u\n", timestamp);
|
||||
meta_window_ungrab_all_keys (grab_window, timestamp);
|
||||
meta_window_ungrab_all_keys (display->grab_window, timestamp);
|
||||
}
|
||||
|
||||
display->grab_timestamp = 0;
|
||||
@@ -1918,8 +1924,6 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
display->grab_resize_timeout_id = 0;
|
||||
}
|
||||
|
||||
meta_window_grab_op_ended (grab_window, grab_op);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
}
|
||||
@@ -2091,6 +2095,35 @@ meta_display_ungrab_window_buttons (MetaDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_display_grab_window_touch (MetaDisplay *display,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { META_VIRTUAL_CORE_POINTER_ID, sizeof (mask_bits), mask_bits };
|
||||
XIGrabModifiers mods = { XIAnyModifier, 0 };
|
||||
|
||||
XISetMask (mask.mask, XI_TouchBegin);
|
||||
XISetMask (mask.mask, XI_TouchUpdate);
|
||||
XISetMask (mask.mask, XI_TouchEnd);
|
||||
|
||||
XIGrabTouchBegin (meta_backend_x11_get_xdisplay (backend),
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
xwindow, False, &mask, 1, &mods);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_display_ungrab_window_touch (MetaDisplay *display,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
XIGrabModifiers mods = { XIAnyModifier, 0 };
|
||||
|
||||
XIUngrabTouchBegin (meta_backend_x11_get_xdisplay (backend),
|
||||
META_VIRTUAL_CORE_POINTER_ID, xwindow, 1, &mods);
|
||||
}
|
||||
|
||||
/* Grab buttons we only grab while unfocused in click-to-focus mode */
|
||||
#define MAX_FOCUS_BUTTON 4
|
||||
void
|
||||
@@ -3194,28 +3227,3 @@ meta_display_get_gesture_tracker (MetaDisplay *display)
|
||||
{
|
||||
return display->gesture_tracker;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_show_restart_message (MetaDisplay *display,
|
||||
const char *message)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
|
||||
g_signal_emit (display,
|
||||
display_signals[SHOW_RESTART_MESSAGE], 0,
|
||||
message, &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_request_restart (MetaDisplay *display)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
|
||||
g_signal_emit (display,
|
||||
display_signals[RESTART], 0,
|
||||
&result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include "config.h"
|
||||
#include "events.h"
|
||||
|
||||
#include "core.h"
|
||||
#include "display-private.h"
|
||||
#include "window-private.h"
|
||||
#include "backends/meta-backend.h"
|
||||
|
@@ -26,11 +26,14 @@
|
||||
#include "bell.h"
|
||||
#include <meta/errors.h>
|
||||
#include "keybindings-private.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
#define EVENT_MASK (SubstructureRedirectMask | \
|
||||
StructureNotifyMask | SubstructureNotifyMask | \
|
||||
ExposureMask | FocusChangeMask)
|
||||
ExposureMask | \
|
||||
ButtonPressMask | ButtonReleaseMask | \
|
||||
PointerMotionMask | PointerMotionHintMask | \
|
||||
EnterWindowMask | LeaveWindowMask | \
|
||||
FocusChangeMask)
|
||||
|
||||
void
|
||||
meta_window_ensure_frame (MetaWindow *window)
|
||||
@@ -160,16 +163,10 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
|
||||
meta_ui_map_frame (frame->window->screen->ui, frame->xwindow);
|
||||
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
if (META_IS_BACKEND_X11 (backend))
|
||||
{
|
||||
/* Since the backend takes keygrabs on another connection, make sure
|
||||
* to sync the GTK+ connection to ensure that the frame window has
|
||||
* been created on the server at this point. */
|
||||
XSync (window->display->xdisplay, False);
|
||||
}
|
||||
}
|
||||
/* Since the backend takes keygrabs on another connection, make sure
|
||||
* to sync the GTK+ connection to ensure that the frame window has
|
||||
* been created on the server at this point. */
|
||||
XSync (window->display->xdisplay, False);
|
||||
|
||||
/* Move keybindings to frame instead of window */
|
||||
meta_window_grab_keys (window);
|
||||
|
@@ -1,5 +1,12 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/**
|
||||
* \file gesture-tracker-private.h Manages gestures on windows/desktop
|
||||
*
|
||||
* Forwards touch events to clutter actors, and accepts/rejects touch sequences
|
||||
* based on the outcome of those.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
*
|
||||
@@ -61,7 +68,7 @@ struct _MetaGestureTrackerClass
|
||||
|
||||
GType meta_gesture_tracker_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaGestureTracker * meta_gesture_tracker_new (void);
|
||||
MetaGestureTracker * meta_gesture_tracker_new (guint autodeny_timeout);
|
||||
|
||||
gboolean meta_gesture_tracker_handle_event (MetaGestureTracker *tracker,
|
||||
const ClutterEvent *event);
|
@@ -19,17 +19,8 @@
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gesture-tracker
|
||||
* @Title: MetaGestureTracker
|
||||
* @Short_Description: Manages gestures on windows/desktop
|
||||
*
|
||||
* Forwards touch events to clutter actors, and accepts/rejects touch sequences
|
||||
* based on the outcome of those.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "meta-gesture-tracker-private.h"
|
||||
#include "gesture-tracker-private.h"
|
||||
#include "meta-surface-actor.h"
|
||||
|
||||
#define DISTANCE_THRESHOLD 30
|
||||
@@ -68,22 +59,18 @@ struct _MetaGestureTrackerPrivate
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_AUTODENY_TIMEOUT,
|
||||
LAST_PROP,
|
||||
PROP_AUTODENY_TIMEOUT = 1
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[LAST_PROP];
|
||||
|
||||
enum {
|
||||
STATE_CHANGED,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
|
||||
#define DEFAULT_AUTODENY_TIMEOUT 150
|
||||
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
|
||||
static void meta_gesture_tracker_untrack_stage (MetaGestureTracker *tracker);
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaGestureTracker, meta_gesture_tracker, G_TYPE_OBJECT)
|
||||
@@ -153,16 +140,14 @@ meta_gesture_tracker_class_init (MetaGestureTrackerClass *klass)
|
||||
object_class->set_property = meta_gesture_tracker_set_property;
|
||||
object_class->get_property = meta_gesture_tracker_get_property;
|
||||
|
||||
obj_props[PROP_AUTODENY_TIMEOUT] = g_param_spec_uint ("autodeny-timeout",
|
||||
"Auto-deny timeout",
|
||||
"Auto-deny timeout",
|
||||
0, G_MAXUINT, DEFAULT_AUTODENY_TIMEOUT,
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, obj_props);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_AUTODENY_TIMEOUT,
|
||||
g_param_spec_uint ("autodeny-timeout",
|
||||
"Auto-deny timeout",
|
||||
"Auto-deny timeout",
|
||||
0, G_MAXUINT, 0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
signals[STATE_CHANGED] =
|
||||
g_signal_new ("state-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
@@ -195,7 +180,8 @@ meta_sequence_info_new (MetaGestureTracker *tracker,
|
||||
guint ms;
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (tracker);
|
||||
ms = priv->autodeny_timeout;
|
||||
ms = (priv->autodeny_timeout) ?
|
||||
priv->autodeny_timeout : DEFAULT_AUTODENY_TIMEOUT;
|
||||
|
||||
info = g_slice_new0 (MetaSequenceInfo);
|
||||
info->tracker = tracker;
|
||||
@@ -351,9 +337,11 @@ meta_gesture_tracker_init (MetaGestureTracker *tracker)
|
||||
}
|
||||
|
||||
MetaGestureTracker *
|
||||
meta_gesture_tracker_new (void)
|
||||
meta_gesture_tracker_new (guint autodeny_timeout)
|
||||
{
|
||||
return g_object_new (META_TYPE_GESTURE_TRACKER, NULL);
|
||||
return g_object_new (META_TYPE_GESTURE_TRACKER,
|
||||
"autodeny-timeout", autodeny_timeout,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
@@ -55,6 +55,7 @@
|
||||
#include <X11/XKBlib.h>
|
||||
#endif
|
||||
|
||||
#include "wayland/meta-wayland.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "x11/window-x11.h"
|
||||
|
||||
@@ -1194,8 +1195,9 @@ meta_window_change_keygrabs (MetaWindow *window,
|
||||
void
|
||||
meta_window_grab_keys (MetaWindow *window)
|
||||
{
|
||||
/* Under Wayland, we don't need to grab at all. */
|
||||
if (meta_is_wayland_compositor ())
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
if (!META_IS_BACKEND_X11 (backend))
|
||||
return;
|
||||
|
||||
if (window->all_keys_grabbed)
|
||||
|
@@ -94,6 +94,26 @@ static GMainLoop *meta_main_loop = NULL;
|
||||
static void prefs_changed_callback (MetaPreference pref,
|
||||
gpointer data);
|
||||
|
||||
/**
|
||||
* log_handler:
|
||||
* @log_domain: the domain the error occurred in (we ignore this)
|
||||
* @log_level: the log level so that we can filter out less
|
||||
* important messages
|
||||
* @message: the message to log
|
||||
* @user_data: arbitrary data (we ignore this)
|
||||
*
|
||||
* Prints log messages. If Mutter was compiled with backtrace support,
|
||||
* also prints a backtrace (see meta_print_backtrace()).
|
||||
*/
|
||||
static void
|
||||
log_handler (const gchar *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const gchar *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
meta_warning ("Log level %d: %s\n", log_level, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_print_compilation_info:
|
||||
*
|
||||
@@ -367,8 +387,6 @@ meta_init (void)
|
||||
meta_clutter_init ();
|
||||
}
|
||||
|
||||
meta_restart_init ();
|
||||
|
||||
/*
|
||||
* XXX: We cannot handle high dpi scaling yet, so fix the scale to 1
|
||||
* for now.
|
||||
@@ -426,10 +444,24 @@ meta_register_with_session (void)
|
||||
int
|
||||
meta_run (void)
|
||||
{
|
||||
const gchar *log_domains[] = {
|
||||
NULL, G_LOG_DOMAIN, "Gtk", "Gdk", "GLib",
|
||||
"Pango", "GLib-GObject", "GThread"
|
||||
};
|
||||
guint i;
|
||||
|
||||
/* Load prefs */
|
||||
meta_prefs_init ();
|
||||
meta_prefs_add_listener (prefs_changed_callback, NULL);
|
||||
|
||||
for (i=0; i<G_N_ELEMENTS(log_domains); i++)
|
||||
g_log_set_handler (log_domains[i],
|
||||
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
|
||||
log_handler, NULL);
|
||||
|
||||
if (g_getenv ("MUTTER_G_FATAL_WARNINGS") != NULL)
|
||||
g_log_set_always_fatal (G_LOG_LEVEL_MASK);
|
||||
|
||||
meta_ui_set_current_theme (meta_prefs_get_theme ());
|
||||
|
||||
/* Try to find some theme that'll work if the theme preference
|
||||
|
@@ -309,16 +309,9 @@ accelerator_parse (const gchar *accelerator,
|
||||
keyval = xkb_keysym_from_name (accelerator, XKB_KEYSYM_CASE_INSENSITIVE);
|
||||
if (keyval == XKB_KEY_NoSymbol)
|
||||
{
|
||||
char *with_xf86 = g_strconcat ("XF86", accelerator, NULL);
|
||||
keyval = xkb_keysym_from_name (with_xf86, XKB_KEYSYM_CASE_INSENSITIVE);
|
||||
g_free (with_xf86);
|
||||
|
||||
if (keyval == XKB_KEY_NoSymbol)
|
||||
{
|
||||
error = TRUE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
error = TRUE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
accelerator += len;
|
||||
|
@@ -1,82 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* SECTION:restart-helper
|
||||
* @short_description: helper program during a restart
|
||||
*
|
||||
* To smoothly restart Mutter, we want to keep the composite
|
||||
* overlay window enabled during the restart. This is done by
|
||||
* spawning this program, which keeps a reference to the the composite
|
||||
* overlay window until Mutter picks it back up.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
Display *display = XOpenDisplay (NULL);
|
||||
Window selection_window;
|
||||
XSetWindowAttributes xwa;
|
||||
unsigned long mask = 0;
|
||||
|
||||
xwa.override_redirect = True;
|
||||
mask |= CWOverrideRedirect;
|
||||
|
||||
|
||||
XCompositeGetOverlayWindow (display, DefaultRootWindow (display));
|
||||
|
||||
selection_window = XCreateWindow (display,
|
||||
DefaultRootWindow (display),
|
||||
-100, -100, 1, 1, 0,
|
||||
0,
|
||||
InputOnly,
|
||||
DefaultVisual (display, DefaultScreen (display)),
|
||||
mask, &xwa);
|
||||
|
||||
XSetSelectionOwner (display,
|
||||
XInternAtom (display, "_MUTTER_RESTART_HELPER", False),
|
||||
selection_window,
|
||||
CurrentTime);
|
||||
|
||||
/* Mutter looks for an (arbitrary) line printed to stdout to know that
|
||||
* we have started and have a reference to the COW. XSync() so that
|
||||
* everything is set on the X server before Mutter starts restarting.
|
||||
*/
|
||||
XSync (display, False);
|
||||
|
||||
printf ("STARTED\n");
|
||||
fflush (stdout);
|
||||
|
||||
while (True)
|
||||
{
|
||||
XEvent xev;
|
||||
|
||||
XNextEvent (display, &xev);
|
||||
/* Mutter restarted and unset the selection to indicate that
|
||||
* it has a reference on the COW again */
|
||||
if (xev.xany.type == SelectionClear)
|
||||
return 0;
|
||||
}
|
||||
}
|
@@ -1,212 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SECTION:restart
|
||||
* @short_description: Smoothly restart the compositor
|
||||
*
|
||||
* There are some cases where we need to restart Mutter in order
|
||||
* to deal with changes in state - the particular case inspiring
|
||||
* this is enabling or disabling stereo output. To make this
|
||||
* fairly smooth for the user, we need to do two things:
|
||||
*
|
||||
* - Display a message to the user and make sure that it is
|
||||
* actually painted before we exit.
|
||||
* - Use a helper program so that the Composite Overlay Window
|
||||
* isn't unmapped and mapped.
|
||||
*
|
||||
* This handles both of these.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
|
||||
#include <meta/main.h>
|
||||
#include "ui.h"
|
||||
#include "util-private.h"
|
||||
#include "display-private.h"
|
||||
|
||||
static gboolean restart_helper_started = FALSE;
|
||||
static gboolean restart_message_shown = FALSE;
|
||||
static gboolean is_restart = FALSE;
|
||||
|
||||
void
|
||||
meta_restart_init (void)
|
||||
{
|
||||
Display *xdisplay = meta_ui_get_display ();
|
||||
Atom atom_restart_helper = XInternAtom (xdisplay, "_MUTTER_RESTART_HELPER", False);
|
||||
Window restart_helper_window = None;
|
||||
|
||||
restart_helper_window = XGetSelectionOwner (xdisplay, atom_restart_helper);
|
||||
if (restart_helper_window)
|
||||
is_restart = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
restart_check_ready (void)
|
||||
{
|
||||
if (restart_helper_started && restart_message_shown)
|
||||
meta_display_request_restart (meta_get_display ());
|
||||
}
|
||||
|
||||
static void
|
||||
restart_helper_read_line_callback (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gsize length;
|
||||
char *line = g_data_input_stream_read_line_finish_utf8 (G_DATA_INPUT_STREAM (source_object),
|
||||
res,
|
||||
&length, &error);
|
||||
if (line == NULL)
|
||||
{
|
||||
meta_warning ("Failed to read output from restart helper%s%s\n",
|
||||
error ? ": " : NULL,
|
||||
error ? error->message : NULL);
|
||||
}
|
||||
else
|
||||
g_free (line); /* We don't actually care what the restart helper outputs */
|
||||
|
||||
g_object_unref (source_object);
|
||||
|
||||
restart_helper_started = TRUE;
|
||||
restart_check_ready ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
restart_message_painted (gpointer data)
|
||||
{
|
||||
restart_message_shown = TRUE;
|
||||
restart_check_ready ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_restart:
|
||||
* @message: message to display to the user.
|
||||
*
|
||||
* Starts the process of restarting the compositor. Note that Mutter's
|
||||
* involvement here is to make the restart visually smooth for the
|
||||
* user - it cannot itself safely reexec a program that embeds libmuttter.
|
||||
* So in order for this to work, the compositor must handle two
|
||||
* signals - MetaDisplay::show-restart-message, to display the
|
||||
* message passed here on the Clutter stage, and ::restart to actually
|
||||
* reexec the compositor.
|
||||
*/
|
||||
void
|
||||
meta_restart (const char *message)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display();
|
||||
GInputStream *unix_stream;
|
||||
GDataInputStream *data_stream;
|
||||
GError *error = NULL;
|
||||
int helper_out_fd;
|
||||
|
||||
static const char * const helper_argv[] = {
|
||||
MUTTER_LIBEXECDIR "/mutter-restart-helper", NULL
|
||||
};
|
||||
|
||||
if (meta_display_show_restart_message (display, message))
|
||||
{
|
||||
/* Wait until the stage was painted */
|
||||
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
|
||||
restart_message_painted,
|
||||
NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Can't show the message, show the message as soon as the
|
||||
* restart helper starts
|
||||
*/
|
||||
restart_message_painted (NULL);
|
||||
}
|
||||
|
||||
/* We also need to wait for the restart helper to get its
|
||||
* reference to the Composite Overlay Window.
|
||||
*/
|
||||
if (!g_spawn_async_with_pipes (NULL, /* working directory */
|
||||
(char **)helper_argv,
|
||||
NULL, /* envp */
|
||||
G_SPAWN_DEFAULT,
|
||||
NULL, NULL, /* child_setup */
|
||||
NULL, /* child_pid */
|
||||
NULL, /* standard_input */
|
||||
&helper_out_fd,
|
||||
NULL, /* standard_error */
|
||||
&error))
|
||||
{
|
||||
meta_warning ("Failed to start restart helper: %s\n", error->message);
|
||||
goto error;
|
||||
}
|
||||
|
||||
unix_stream = g_unix_input_stream_new (helper_out_fd, TRUE);
|
||||
data_stream = g_data_input_stream_new (unix_stream);
|
||||
g_object_unref (unix_stream);
|
||||
|
||||
g_data_input_stream_read_line_async (data_stream, G_PRIORITY_DEFAULT,
|
||||
NULL, restart_helper_read_line_callback,
|
||||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
meta_warning ("Failed to read from restart helper: %s\n", error->message);
|
||||
g_object_unref (data_stream);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
/* If starting the restart helper fails, then we just go ahead and restart
|
||||
* immediately. We won't get a smooth transition, since the overlay window
|
||||
* will be destroyed and recreated, but otherwise it will work fine.
|
||||
*/
|
||||
restart_helper_started = TRUE;
|
||||
restart_check_ready ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
meta_restart_finish (void)
|
||||
{
|
||||
if (is_restart)
|
||||
{
|
||||
Display *xdisplay = meta_display_get_xdisplay (meta_get_display ());
|
||||
Atom atom_restart_helper = XInternAtom (xdisplay, "_MUTTER_RESTART_HELPER", False);
|
||||
XSetSelectionOwner (xdisplay, atom_restart_helper, None, CurrentTime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_is_restart:
|
||||
*
|
||||
* Returns %TRUE if this instance of Mutter comes from Mutter
|
||||
* restarting itself (for example to enable/disable stereo.)
|
||||
* See meta_restart(). If this is the case, any startup visuals
|
||||
* or animations should be suppressed.
|
||||
*/
|
||||
gboolean
|
||||
meta_is_restart (void)
|
||||
{
|
||||
return is_restart;
|
||||
}
|
@@ -119,8 +119,6 @@ struct _MetaScreen
|
||||
* and restack them below a guard window. When using a compositor
|
||||
* this allows us to provide live previews of unmapped windows */
|
||||
Window guard_window;
|
||||
|
||||
Window composite_overlay_window;
|
||||
};
|
||||
|
||||
struct _MetaScreenClass
|
||||
|
@@ -45,7 +45,6 @@
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
#include <locale.h>
|
||||
@@ -56,8 +55,6 @@
|
||||
#include "x11/window-x11.h"
|
||||
#include "x11/xprops.h"
|
||||
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
static char* get_screen_name (MetaDisplay *display,
|
||||
int number);
|
||||
|
||||
@@ -472,24 +469,13 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
|
||||
XStoreName (xdisplay, guard_window, "mutter guard window");
|
||||
|
||||
{
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
Display *backend_xdisplay = meta_backend_x11_get_xdisplay (backend);
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Motion);
|
||||
|
||||
/* Sync on the connection we created the window on to
|
||||
* make sure it's created before we select on it on the
|
||||
* backend connection. */
|
||||
XSync (xdisplay, False);
|
||||
|
||||
XISelectEvents (backend_xdisplay, guard_window, &mask, 1);
|
||||
}
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Motion);
|
||||
XISelectEvents (xdisplay, guard_window, &mask, 1);
|
||||
}
|
||||
|
||||
stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
||||
@@ -506,15 +492,6 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
|
||||
return guard_window;
|
||||
}
|
||||
|
||||
/* Set a black background on the root window so that we don't
|
||||
* see confusing old copies of old windows when debugging
|
||||
* and testing. */
|
||||
static void
|
||||
meta_screen_set_background (MetaScreen *screen)
|
||||
{
|
||||
XSetWindowBackground (screen->display->xdisplay, screen->xroot, 0x00000000);
|
||||
}
|
||||
|
||||
MetaScreen*
|
||||
meta_screen_new (MetaDisplay *display,
|
||||
int number,
|
||||
@@ -634,15 +611,24 @@ meta_screen_new (MetaDisplay *display,
|
||||
/* select our root window events */
|
||||
meta_error_trap_push (display);
|
||||
|
||||
/* We need to or with the existing event mask since
|
||||
* gtk+ may be interested in other events.
|
||||
*/
|
||||
{
|
||||
long event_mask;
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
XWindowAttributes attr;
|
||||
|
||||
meta_core_add_old_event_mask (xdisplay, xroot, &mask);
|
||||
|
||||
XISetMask (mask.mask, XI_KeyPress);
|
||||
XISetMask (mask.mask, XI_KeyRelease);
|
||||
XISetMask (mask.mask, XI_Enter);
|
||||
XISetMask (mask.mask, XI_Leave);
|
||||
XISetMask (mask.mask, XI_FocusIn);
|
||||
XISetMask (mask.mask, XI_FocusOut);
|
||||
XISetMask (mask.mask, XI_Motion);
|
||||
#ifdef HAVE_XI23
|
||||
if (META_DISPLAY_HAS_XINPUT_23 (display))
|
||||
{
|
||||
@@ -654,6 +640,9 @@ meta_screen_new (MetaDisplay *display,
|
||||
|
||||
event_mask = (SubstructureRedirectMask | SubstructureNotifyMask |
|
||||
StructureNotifyMask | ColormapChangeMask | PropertyChangeMask);
|
||||
if (XGetWindowAttributes (xdisplay, xroot, &attr))
|
||||
event_mask |= attr.your_event_mask;
|
||||
|
||||
XSelectInput (xdisplay, xroot, event_mask);
|
||||
}
|
||||
|
||||
@@ -667,9 +656,6 @@ meta_screen_new (MetaDisplay *display,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Select for cursor changes so the cursor tracker is up to date. */
|
||||
XFixesSelectCursorInput (xdisplay, xroot, XFixesDisplayCursorNotifyMask);
|
||||
|
||||
screen = g_object_new (META_TYPE_SCREEN, NULL);
|
||||
screen->closing = 0;
|
||||
|
||||
@@ -710,16 +696,9 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->starting_corner = META_SCREEN_TOPLEFT;
|
||||
screen->guard_window = None;
|
||||
|
||||
screen->composite_overlay_window = XCompositeGetOverlayWindow (xdisplay, xroot);
|
||||
|
||||
/* Now that we've gotten taken a reference count on the COW, we
|
||||
* can close the helper that is holding on to it */
|
||||
meta_restart_finish ();
|
||||
|
||||
reload_monitor_infos (screen);
|
||||
|
||||
meta_screen_set_cursor (screen, META_CURSOR_DEFAULT);
|
||||
meta_screen_set_background (screen);
|
||||
|
||||
/* Handle creating a no_focus_window for this screen */
|
||||
screen->no_focus_window =
|
||||
@@ -797,6 +776,7 @@ meta_screen_init_workspaces (MetaScreen *screen)
|
||||
else
|
||||
meta_verbose ("No _NET_CURRENT_DESKTOP present\n");
|
||||
|
||||
meta_workspace_activate (screen->workspaces->data, timestamp);
|
||||
update_num_workspaces (screen, timestamp);
|
||||
|
||||
set_workspace_names (screen);
|
||||
@@ -807,8 +787,6 @@ meta_screen_init_workspaces (MetaScreen *screen)
|
||||
|
||||
if (current_workspace != NULL)
|
||||
meta_workspace_activate (current_workspace, timestamp);
|
||||
else
|
||||
meta_workspace_activate (screen->workspaces->data, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -821,6 +799,8 @@ meta_screen_free (MetaScreen *screen,
|
||||
|
||||
screen->closing += 1;
|
||||
|
||||
meta_display_grab (display);
|
||||
|
||||
meta_compositor_unmanage (screen->display->compositor);
|
||||
|
||||
meta_display_unmanage_windows_for_screen (display, screen, timestamp);
|
||||
@@ -877,6 +857,9 @@ meta_screen_free (MetaScreen *screen,
|
||||
g_free (screen->screen_name);
|
||||
|
||||
g_object_unref (screen);
|
||||
|
||||
XFlush (display->xdisplay);
|
||||
meta_display_ungrab (display);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -234,36 +234,32 @@ meta_stack_op_dump (MetaStackOp *op,
|
||||
g_free (window_id);
|
||||
}
|
||||
|
||||
static void
|
||||
stack_dump (GArray *stack)
|
||||
{
|
||||
guint i;
|
||||
|
||||
meta_push_no_msg_prefix ();
|
||||
for (i = 0; i < stack->len; i++)
|
||||
{
|
||||
MetaStackWindow *window = &g_array_index (stack, MetaStackWindow, i);
|
||||
char *window_id = get_window_id (window);
|
||||
meta_topic (META_DEBUG_STACK, " %s", window_id);
|
||||
g_free (window_id);
|
||||
}
|
||||
meta_topic (META_DEBUG_STACK, "\n");
|
||||
meta_pop_no_msg_prefix ();
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stack_tracker_dump (MetaStackTracker *tracker)
|
||||
{
|
||||
guint i;
|
||||
GList *l;
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "MetaStackTracker state (screen=%d)\n", tracker->screen->number);
|
||||
meta_push_no_msg_prefix ();
|
||||
meta_topic (META_DEBUG_STACK, " xserver_serial: %ld\n", tracker->xserver_serial);
|
||||
meta_topic (META_DEBUG_STACK, " xserver_stack: ");
|
||||
stack_dump (tracker->xserver_stack);
|
||||
meta_topic (META_DEBUG_STACK, " verfied_stack: ");
|
||||
stack_dump (tracker->verified_stack);
|
||||
meta_topic (META_DEBUG_STACK, " unverified_predictions: [");
|
||||
for (i = 0; i < tracker->xserver_stack->len; i++)
|
||||
{
|
||||
MetaStackWindow *window = &g_array_index (tracker->xserver_stack, MetaStackWindow, i);
|
||||
char *window_id = get_window_id (window);
|
||||
meta_topic (META_DEBUG_STACK, " %s", window_id);
|
||||
g_free (window_id);
|
||||
}
|
||||
meta_topic (META_DEBUG_STACK, "\n verfied_stack: ");
|
||||
for (i = 0; i < tracker->verified_stack->len; i++)
|
||||
{
|
||||
MetaStackWindow *window = &g_array_index (tracker->verified_stack, MetaStackWindow, i);
|
||||
char *window_id = get_window_id (window);
|
||||
meta_topic (META_DEBUG_STACK, " %s", window_id);
|
||||
g_free (window_id);
|
||||
}
|
||||
meta_topic (META_DEBUG_STACK, "\n unverified_predictions: [");
|
||||
for (l = tracker->unverified_predictions->head; l; l = l->next)
|
||||
{
|
||||
MetaStackOp *op = l->data;
|
||||
@@ -273,8 +269,15 @@ meta_stack_tracker_dump (MetaStackTracker *tracker)
|
||||
if (tracker->predicted_stack)
|
||||
{
|
||||
meta_topic (META_DEBUG_STACK, "\n predicted_stack: ");
|
||||
stack_dump (tracker->predicted_stack);
|
||||
for (i = 0; i < tracker->predicted_stack->len; i++)
|
||||
{
|
||||
MetaStackWindow *window = &g_array_index (tracker->predicted_stack, MetaStackWindow, i);
|
||||
char *window_id = get_window_id (window);
|
||||
meta_topic (META_DEBUG_STACK, " %s", window_id);
|
||||
g_free (window_id);
|
||||
}
|
||||
}
|
||||
meta_topic (META_DEBUG_STACK, "\n");
|
||||
meta_pop_no_msg_prefix ();
|
||||
}
|
||||
|
||||
@@ -482,12 +485,14 @@ requery_xserver_stack (MetaStackTracker *tracker)
|
||||
screen->xroot,
|
||||
&ignored1, &ignored2, &children, &n_children);
|
||||
|
||||
tracker->xserver_stack = g_array_sized_new (FALSE, FALSE, sizeof (MetaStackWindow), n_children);
|
||||
tracker->xserver_stack =
|
||||
g_array_sized_new (FALSE, FALSE, sizeof (MetaStackWindow), n_children);
|
||||
g_array_set_size (tracker->xserver_stack, n_children);
|
||||
|
||||
for (i = 0; i < n_children; i++)
|
||||
{
|
||||
MetaStackWindow *window = &g_array_index (tracker->xserver_stack, MetaStackWindow, i);
|
||||
MetaStackWindow *window =
|
||||
&g_array_index (tracker->xserver_stack, MetaStackWindow, i);
|
||||
window->any.type = META_WINDOW_CLIENT_TYPE_X11;
|
||||
window->x11.xwindow = children[i];
|
||||
}
|
||||
@@ -709,10 +714,14 @@ meta_stack_tracker_record_lower (MetaStackTracker *tracker,
|
||||
*
|
||||
* Return value: %TRUE if the predicted state is consistent with
|
||||
* receiving the given @op from X, else %FALSE.
|
||||
*
|
||||
* @modified will be set to %TRUE if tracker->verified_stack is
|
||||
* changed by applying any newly validated operations, else %FALSE.
|
||||
*/
|
||||
static gboolean
|
||||
stack_tracker_verify_predictions (MetaStackTracker *tracker,
|
||||
MetaStackOp *op)
|
||||
MetaStackOp *op,
|
||||
gboolean *modified)
|
||||
{
|
||||
GArray *tmp_predicted_stack = NULL;
|
||||
GArray *predicted_stack;
|
||||
@@ -722,8 +731,6 @@ stack_tracker_verify_predictions (MetaStackTracker *tracker,
|
||||
* passed to this api. */
|
||||
g_return_val_if_fail (op->any.window.any.type == META_WINDOW_CLIENT_TYPE_X11, FALSE);
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "Verifying predictions:\n");
|
||||
|
||||
if (tracker->unverified_predictions->length)
|
||||
{
|
||||
GList *l;
|
||||
@@ -743,9 +750,6 @@ stack_tracker_verify_predictions (MetaStackTracker *tracker,
|
||||
else
|
||||
predicted_stack = tracker->verified_stack;
|
||||
|
||||
meta_topic (META_DEBUG_STACK, " predicted_stack: ");
|
||||
stack_dump (predicted_stack);
|
||||
|
||||
switch (op->any.type)
|
||||
{
|
||||
case STACK_OP_ADD:
|
||||
@@ -821,6 +825,7 @@ verified:
|
||||
meta_stack_op_free (queued_op);
|
||||
}
|
||||
|
||||
*modified = modified_stack;
|
||||
if (modified_stack)
|
||||
{
|
||||
g_array_free (tracker->verified_stack, TRUE);
|
||||
@@ -842,6 +847,8 @@ not_verified:
|
||||
tracker->predicted_stack = NULL;
|
||||
}
|
||||
|
||||
*modified = FALSE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -874,17 +881,17 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
||||
* windows and free the queue of unverified_predictions.
|
||||
*
|
||||
* - Iterate through the x windows listed in verified_stack at the
|
||||
* same time as iterating the windows in xserver_stack. (Stop
|
||||
* when we reach the end of the xserver_stack)
|
||||
* same time as iterating the windows in xserver_list. (Stop
|
||||
* when we reach the end of the xserver_list)
|
||||
* - If the window found doesn't match the window expected
|
||||
* according to the order of xserver_stack then:
|
||||
* according to the order of xserver_list then:
|
||||
* - Look ahead for the window we were expecting and restack
|
||||
* that above the previous X window. If we fail to find the
|
||||
* expected window then create a new entry for it and stack
|
||||
* that.
|
||||
*
|
||||
* - Continue to iterate through verified_stack for any remaining
|
||||
* X windows that we now know aren't in the xserver_stack and
|
||||
* X windows that we now know aren't in the xserver_list and
|
||||
* remove them.
|
||||
*
|
||||
* - Free ->predicted_stack if any.
|
||||
@@ -902,11 +909,15 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
||||
g_queue_clear (tracker->unverified_predictions);
|
||||
|
||||
j = 0;
|
||||
expected_xwindow = &g_array_index (tracker->xserver_stack, MetaStackWindow, j);
|
||||
expected_xwindow =
|
||||
&g_array_index (tracker->xserver_stack, MetaStackWindow, j);
|
||||
|
||||
for (i = 0; i < tracker->verified_stack->len; )
|
||||
for (i = 0;
|
||||
i < tracker->verified_stack->len;
|
||||
)
|
||||
{
|
||||
MetaStackWindow *current = &g_array_index (tracker->verified_stack, MetaStackWindow, i);
|
||||
MetaStackWindow *current =
|
||||
&g_array_index (tracker->verified_stack, MetaStackWindow, i);
|
||||
|
||||
if (current->any.type != META_WINDOW_CLIENT_TYPE_X11)
|
||||
{
|
||||
@@ -943,7 +954,8 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
||||
|
||||
/* Technically we only need to look forward from i if we
|
||||
* wanted to optimize this a bit... */
|
||||
expected_index = find_window (tracker->verified_stack, expected_xwindow);
|
||||
expected_index =
|
||||
find_window (tracker->verified_stack, expected_xwindow);
|
||||
|
||||
if (expected_index >= 0)
|
||||
{
|
||||
@@ -981,7 +993,8 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
||||
i++;
|
||||
|
||||
j++;
|
||||
expected_xwindow = &g_array_index (tracker->xserver_stack, MetaStackWindow, j);
|
||||
expected_xwindow =
|
||||
&g_array_index (tracker->xserver_stack, MetaStackWindow, j);
|
||||
|
||||
if (j >= tracker->xserver_stack->len)
|
||||
break;
|
||||
@@ -991,7 +1004,8 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
||||
* xserver_stack and so we can remove them. */
|
||||
while (i < tracker->verified_stack->len)
|
||||
{
|
||||
MetaStackWindow *current = &g_array_index (tracker->verified_stack, MetaStackWindow, i);
|
||||
MetaStackWindow *current =
|
||||
&g_array_index (tracker->verified_stack, MetaStackWindow, i);
|
||||
|
||||
if (current->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
g_array_remove_index (tracker->verified_stack, i);
|
||||
@@ -1002,10 +1016,11 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
||||
}
|
||||
|
||||
/* If we get to the end of verified_list and there are any remaining
|
||||
* entries in xserver_stack then append them all to the end */
|
||||
* entries in xserver_list then append them all to the end */
|
||||
for (; j < tracker->xserver_stack->len; j++)
|
||||
{
|
||||
MetaStackWindow *current = &g_array_index (tracker->xserver_stack, MetaStackWindow, j);
|
||||
MetaStackWindow *current =
|
||||
&g_array_index (tracker->xserver_stack, MetaStackWindow, j);
|
||||
g_array_append_val (tracker->verified_stack, *current);
|
||||
|
||||
modified_stack = TRUE;
|
||||
@@ -1029,13 +1044,19 @@ static void
|
||||
stack_tracker_event_received (MetaStackTracker *tracker,
|
||||
MetaStackOp *op)
|
||||
{
|
||||
/* If the event is older than our latest requery, then it's
|
||||
* already included in our tree. Just ignore it. */
|
||||
if (op->any.serial < tracker->xserver_serial)
|
||||
return;
|
||||
gboolean need_sync = FALSE;
|
||||
gboolean verified;
|
||||
|
||||
meta_stack_op_dump (op, "Stack op event received: ", "\n");
|
||||
|
||||
if (op->any.serial < tracker->xserver_serial)
|
||||
{
|
||||
/* g_warning ("Spurious X event received affecting stack; doing full re-query"); */
|
||||
resync_verified_stack_with_xserver_stack (tracker);
|
||||
meta_stack_tracker_dump (tracker);
|
||||
return;
|
||||
}
|
||||
|
||||
tracker->xserver_serial = op->any.serial;
|
||||
|
||||
/* XXX: With the design we have ended up with it looks like we've
|
||||
@@ -1049,8 +1070,13 @@ stack_tracker_event_received (MetaStackTracker *tracker,
|
||||
*/
|
||||
meta_stack_op_apply (op, tracker->xserver_stack);
|
||||
|
||||
if (!stack_tracker_verify_predictions (tracker, op))
|
||||
resync_verified_stack_with_xserver_stack (tracker);
|
||||
verified = stack_tracker_verify_predictions (tracker, op, &need_sync);
|
||||
if (!verified)
|
||||
{
|
||||
resync_verified_stack_with_xserver_stack (tracker);
|
||||
meta_stack_tracker_dump (tracker);
|
||||
return;
|
||||
}
|
||||
|
||||
meta_stack_tracker_dump (tracker);
|
||||
}
|
||||
|
@@ -43,6 +43,7 @@
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "x11/iconcache.h"
|
||||
#include "x11/group-private.h"
|
||||
|
||||
#include "wayland/meta-wayland-types.h"
|
||||
@@ -106,6 +107,9 @@ struct _MetaWindow
|
||||
|
||||
GdkPixbuf *icon;
|
||||
GdkPixbuf *mini_icon;
|
||||
MetaIconCache icon_cache;
|
||||
Pixmap wm_hints_pixmap;
|
||||
Pixmap wm_hints_mask;
|
||||
|
||||
MetaWindowType type;
|
||||
|
||||
@@ -162,7 +166,7 @@ struct _MetaWindow
|
||||
* that to toggle between normal/tiled or maximized/tiled states. */
|
||||
guint saved_maximize : 1;
|
||||
int tile_monitor_number;
|
||||
int preferred_output_winsys_id;
|
||||
int preferred_output_id;
|
||||
|
||||
/* Whether we're shaded */
|
||||
guint shaded : 1;
|
||||
@@ -347,6 +351,10 @@ struct _MetaWindow
|
||||
/* whether or not the window is from a program running on another machine */
|
||||
guint is_remote : 1;
|
||||
|
||||
/* Used for Wayland -- surfaces can behave as if they were unmapped if
|
||||
* they have a NULL buffer attached... */
|
||||
guint surface_mapped;
|
||||
|
||||
/* if non-NULL, the bounds of the window frame */
|
||||
cairo_region_t *frame_bounds;
|
||||
|
||||
@@ -480,9 +488,6 @@ struct _MetaWindowClass
|
||||
void (*get_default_skip_hints) (MetaWindow *window,
|
||||
gboolean *skip_taskbar_out,
|
||||
gboolean *skip_pager_out);
|
||||
gboolean (*update_icon) (MetaWindow *window,
|
||||
GdkPixbuf **icon,
|
||||
GdkPixbuf **mini_icon);
|
||||
};
|
||||
|
||||
/* These differ from window->has_foo_func in that they consider
|
||||
@@ -627,6 +632,8 @@ void meta_window_stack_just_below (MetaWindow *window,
|
||||
void meta_window_set_user_time (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_window_update_icon_now (MetaWindow *window);
|
||||
|
||||
void meta_window_update_for_monitors_changed (MetaWindow *window);
|
||||
void meta_window_update_on_all_workspaces (MetaWindow *window);
|
||||
|
||||
@@ -668,6 +675,9 @@ void meta_window_handle_leave (MetaWindow *window);
|
||||
gboolean meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
const ClutterEvent *event);
|
||||
|
||||
void meta_window_set_surface_mapped (MetaWindow *window,
|
||||
gboolean surface_mapped);
|
||||
|
||||
void meta_window_get_client_area_rect (const MetaWindow *window,
|
||||
cairo_rectangle_int_t *rect);
|
||||
void meta_window_get_titlebar_rect (MetaWindow *window,
|
||||
@@ -678,6 +688,8 @@ void meta_window_activate_full (MetaWindow *window,
|
||||
MetaClientType source_indication,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
gboolean meta_window_is_client_decorated (MetaWindow *window);
|
||||
|
||||
void meta_window_update_monitor (MetaWindow *window,
|
||||
gboolean user_op);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -34,9 +34,6 @@ gboolean meta_get_replace_current_wm (void); /* Actually defined in util
|
||||
void meta_set_wm_name (const char *wm_name);
|
||||
void meta_set_gnome_wm_keybindings (const char *wm_keybindings);
|
||||
|
||||
void meta_restart (const char *message);
|
||||
gboolean meta_is_restart (void);
|
||||
|
||||
/**
|
||||
* MetaExitCode:
|
||||
* @META_EXIT_SUCCESS: Success
|
||||
|
@@ -256,7 +256,6 @@ gboolean meta_window_is_always_on_all_workspaces (MetaWindow *window);
|
||||
gboolean meta_window_is_above (MetaWindow *window);
|
||||
gboolean meta_window_allows_move (MetaWindow *window);
|
||||
gboolean meta_window_allows_resize (MetaWindow *window);
|
||||
gboolean meta_window_is_client_decorated (MetaWindow *window);
|
||||
|
||||
gboolean meta_window_titlebar_is_onscreen (MetaWindow *window);
|
||||
void meta_window_shove_titlebar_onscreen (MetaWindow *window);
|
||||
|
@@ -1579,6 +1579,7 @@ meta_frames_motion_notify_event (GtkWidget *widget,
|
||||
MetaUIFrame *frame;
|
||||
MetaFrames *frames;
|
||||
MetaFrameControl control;
|
||||
int x, y;
|
||||
|
||||
frames = META_FRAMES (widget);
|
||||
frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
|
||||
@@ -1587,7 +1588,9 @@ meta_frames_motion_notify_event (GtkWidget *widget,
|
||||
|
||||
frames->last_motion_frame = frame;
|
||||
|
||||
control = get_control (frames, frame, event->x, event->y);
|
||||
gdk_window_get_device_position (frame->window, event->device,
|
||||
&x, &y, NULL);
|
||||
control = get_control (frames, frame, x, y);
|
||||
|
||||
if (frame->button_state == META_BUTTON_STATE_PRESSED)
|
||||
{
|
||||
|
@@ -65,7 +65,7 @@ free_buffer (guchar *pixels, gpointer data)
|
||||
}
|
||||
|
||||
static GdkPixbuf*
|
||||
blank_pixbuf (int width, int height)
|
||||
blank_pixbuf (int width, int height, gboolean no_padding)
|
||||
{
|
||||
guchar *buf;
|
||||
int rowstride;
|
||||
@@ -73,15 +73,18 @@ blank_pixbuf (int width, int height)
|
||||
g_return_val_if_fail (width > 0, NULL);
|
||||
g_return_val_if_fail (height > 0, NULL);
|
||||
|
||||
/* Always align rows to 32-bit boundaries */
|
||||
rowstride = 4 * ((4 * width + 4) / 4);
|
||||
if (no_padding)
|
||||
rowstride = width * 3;
|
||||
else
|
||||
/* Always align rows to 32-bit boundaries */
|
||||
rowstride = 4 * ((3 * width + 3) / 4);
|
||||
|
||||
buf = g_try_malloc (height * rowstride);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
return gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB,
|
||||
TRUE, 8,
|
||||
FALSE, 8,
|
||||
width, height, rowstride,
|
||||
free_buffer, NULL);
|
||||
}
|
||||
@@ -193,14 +196,14 @@ meta_gradient_create_interwoven (int width,
|
||||
{
|
||||
|
||||
int i, j, k, l, ll;
|
||||
long r1, g1, b1, a1, dr1, dg1, db1, da1;
|
||||
long r2, g2, b2, a2, dr2, dg2, db2, da2;
|
||||
long r1, g1, b1, dr1, dg1, db1;
|
||||
long r2, g2, b2, dr2, dg2, db2;
|
||||
GdkPixbuf *pixbuf;
|
||||
unsigned char *ptr;
|
||||
unsigned char *pixels;
|
||||
int rowstride;
|
||||
|
||||
pixbuf = blank_pixbuf (width, height);
|
||||
pixbuf = blank_pixbuf (width, height, FALSE);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -210,22 +213,18 @@ meta_gradient_create_interwoven (int width,
|
||||
r1 = (long)(colors1[0].red*0xffffff);
|
||||
g1 = (long)(colors1[0].green*0xffffff);
|
||||
b1 = (long)(colors1[0].blue*0xffffff);
|
||||
a1 = (long)(colors1[0].alpha*0xffffff);
|
||||
|
||||
r2 = (long)(colors2[0].red*0xffffff);
|
||||
g2 = (long)(colors2[0].green*0xffffff);
|
||||
b2 = (long)(colors2[0].blue*0xffffff);
|
||||
a2 = (long)(colors2[0].alpha*0xffffff);
|
||||
|
||||
dr1 = ((colors1[1].red-colors1[0].red)*0xffffff)/(int)height;
|
||||
dg1 = ((colors1[1].green-colors1[0].green)*0xffffff)/(int)height;
|
||||
db1 = ((colors1[1].blue-colors1[0].blue)*0xffffff)/(int)height;
|
||||
da1 = ((colors1[1].alpha-colors1[0].alpha)*0xffffff)/(int)height;
|
||||
|
||||
dr2 = ((colors2[1].red-colors2[0].red)*0xffffff)/(int)height;
|
||||
dg2 = ((colors2[1].green-colors2[0].green)*0xffffff)/(int)height;
|
||||
db2 = ((colors2[1].blue-colors2[0].blue)*0xffffff)/(int)height;
|
||||
da2 = ((colors2[1].alpha-colors2[0].alpha)*0xffffff)/(int)height;
|
||||
|
||||
for (i=0,k=0,l=0,ll=thickness1; i<height; i++)
|
||||
{
|
||||
@@ -236,19 +235,17 @@ meta_gradient_create_interwoven (int width,
|
||||
ptr[0] = (unsigned char) (r1>>16);
|
||||
ptr[1] = (unsigned char) (g1>>16);
|
||||
ptr[2] = (unsigned char) (b1>>16);
|
||||
ptr[3] = (unsigned char) (a1>>16);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr[0] = (unsigned char) (r2>>16);
|
||||
ptr[1] = (unsigned char) (g2>>16);
|
||||
ptr[2] = (unsigned char) (b2>>16);
|
||||
ptr[3] = (unsigned char) (a2>>16);
|
||||
}
|
||||
|
||||
for (j=1; j <= width/2; j *= 2)
|
||||
memcpy (&(ptr[j*4]), ptr, j*4);
|
||||
memcpy (&(ptr[j*4]), ptr, (width - j)*4);
|
||||
memcpy (&(ptr[j*3]), ptr, j*3);
|
||||
memcpy (&(ptr[j*3]), ptr, (width - j)*3);
|
||||
|
||||
if (++l == ll)
|
||||
{
|
||||
@@ -267,12 +264,10 @@ meta_gradient_create_interwoven (int width,
|
||||
r1+=dr1;
|
||||
g1+=dg1;
|
||||
b1+=db1;
|
||||
a1+=da1;
|
||||
|
||||
r2+=dr2;
|
||||
g2+=dg2;
|
||||
b2+=db2;
|
||||
a2+=da2;
|
||||
}
|
||||
|
||||
return pixbuf;
|
||||
@@ -297,15 +292,15 @@ meta_gradient_create_horizontal (int width, int height,
|
||||
const GdkRGBA *to)
|
||||
{
|
||||
int i;
|
||||
long r, g, b, a, dr, dg, db, da;
|
||||
long r, g, b, dr, dg, db;
|
||||
GdkPixbuf *pixbuf;
|
||||
unsigned char *ptr;
|
||||
unsigned char *pixels;
|
||||
int r0, g0, b0, a0;
|
||||
int rf, gf, bf, af;
|
||||
int r0, g0, b0;
|
||||
int rf, gf, bf;
|
||||
int rowstride;
|
||||
|
||||
pixbuf = blank_pixbuf (width, height);
|
||||
pixbuf = blank_pixbuf (width, height, FALSE);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -316,32 +311,26 @@ meta_gradient_create_horizontal (int width, int height,
|
||||
r0 = (guchar) (from->red * 0xff);
|
||||
g0 = (guchar) (from->green * 0xff);
|
||||
b0 = (guchar) (from->blue * 0xff);
|
||||
a0 = (guchar) (from->alpha * 0xff);
|
||||
rf = (guchar) (to->red * 0xff);
|
||||
gf = (guchar) (to->green * 0xff);
|
||||
bf = (guchar) (to->blue * 0xff);
|
||||
af = (guchar) (to->alpha * 0xff);
|
||||
|
||||
r = r0 << 16;
|
||||
g = g0 << 16;
|
||||
b = b0 << 16;
|
||||
a = a0 << 16;
|
||||
|
||||
dr = ((rf-r0)<<16)/(int)width;
|
||||
dg = ((gf-g0)<<16)/(int)width;
|
||||
db = ((bf-b0)<<16)/(int)width;
|
||||
da = ((af-a0)<<16)/(int)width;
|
||||
/* render the first line */
|
||||
for (i=0; i<width; i++)
|
||||
{
|
||||
*(ptr++) = (unsigned char)(r>>16);
|
||||
*(ptr++) = (unsigned char)(g>>16);
|
||||
*(ptr++) = (unsigned char)(b>>16);
|
||||
*(ptr++) = (unsigned char)(a>>16);
|
||||
r += dr;
|
||||
g += dg;
|
||||
b += db;
|
||||
a += da;
|
||||
}
|
||||
|
||||
/* copy the first line to the other lines */
|
||||
@@ -371,15 +360,15 @@ meta_gradient_create_vertical (int width, int height,
|
||||
const GdkRGBA *to)
|
||||
{
|
||||
int i, j;
|
||||
long r, g, b, a, dr, dg, db, da;
|
||||
long r, g, b, dr, dg, db;
|
||||
GdkPixbuf *pixbuf;
|
||||
unsigned char *ptr;
|
||||
int r0, g0, b0, a0;
|
||||
int rf, gf, bf, af;
|
||||
int r0, g0, b0;
|
||||
int rf, gf, bf;
|
||||
int rowstride;
|
||||
unsigned char *pixels;
|
||||
|
||||
pixbuf = blank_pixbuf (width, height);
|
||||
pixbuf = blank_pixbuf (width, height, FALSE);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -389,21 +378,17 @@ meta_gradient_create_vertical (int width, int height,
|
||||
r0 = (guchar) (from->red * 0xff);
|
||||
g0 = (guchar) (from->green * 0xff);
|
||||
b0 = (guchar) (from->blue * 0xff);
|
||||
a0 = (guchar) (from->alpha * 0xff);
|
||||
rf = (guchar) (to->red * 0xff);
|
||||
gf = (guchar) (to->green * 0xff);
|
||||
bf = (guchar) (to->blue * 0xff);
|
||||
af = (guchar) (to->alpha * 0xff);
|
||||
|
||||
r = r0<<16;
|
||||
g = g0<<16;
|
||||
b = b0<<16;
|
||||
a = a0<<16;
|
||||
|
||||
dr = ((rf-r0)<<16)/(int)height;
|
||||
dg = ((gf-g0)<<16)/(int)height;
|
||||
db = ((bf-b0)<<16)/(int)height;
|
||||
da = ((af-a0)<<16)/(int)height;
|
||||
|
||||
for (i=0; i<height; i++)
|
||||
{
|
||||
@@ -412,16 +397,14 @@ meta_gradient_create_vertical (int width, int height,
|
||||
ptr[0] = (unsigned char)(r>>16);
|
||||
ptr[1] = (unsigned char)(g>>16);
|
||||
ptr[2] = (unsigned char)(b>>16);
|
||||
ptr[3] = (unsigned char)(a>>16);
|
||||
|
||||
for (j=1; j <= width/2; j *= 2)
|
||||
memcpy (&(ptr[j*4]), ptr, j*4);
|
||||
memcpy (&(ptr[j*4]), ptr, (width - j)*4);
|
||||
memcpy (&(ptr[j*3]), ptr, j*3);
|
||||
memcpy (&(ptr[j*3]), ptr, (width - j)*3);
|
||||
|
||||
r+=dr;
|
||||
g+=dg;
|
||||
b+=db;
|
||||
a+=da;
|
||||
}
|
||||
return pixbuf;
|
||||
}
|
||||
@@ -459,7 +442,7 @@ meta_gradient_create_diagonal (int width, int height,
|
||||
else if (height == 1)
|
||||
return meta_gradient_create_horizontal (width, height, from, to);
|
||||
|
||||
pixbuf = blank_pixbuf (width, height);
|
||||
pixbuf = blank_pixbuf (width, height, FALSE);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -476,12 +459,12 @@ meta_gradient_create_diagonal (int width, int height,
|
||||
ptr = gdk_pixbuf_get_pixels (tmp);
|
||||
|
||||
a = ((float)(width - 1))/((float)(height - 1));
|
||||
width = width * 4;
|
||||
width = width * 3;
|
||||
|
||||
/* copy the first line to the other lines with corresponding offset */
|
||||
for (j=0, offset=0.0; j<rowstride*height; j += rowstride)
|
||||
{
|
||||
memcpy (&(pixels[j]), &ptr[4*(int)offset], width);
|
||||
memcpy (&(pixels[j]), &ptr[3*(int)offset], width);
|
||||
offset += a;
|
||||
}
|
||||
|
||||
@@ -496,7 +479,7 @@ meta_gradient_create_multi_horizontal (int width, int height,
|
||||
int count)
|
||||
{
|
||||
int i, j, k;
|
||||
long r, g, b, a, dr, dg, db, da;
|
||||
long r, g, b, dr, dg, db;
|
||||
GdkPixbuf *pixbuf;
|
||||
unsigned char *ptr;
|
||||
unsigned char *pixels;
|
||||
@@ -505,7 +488,7 @@ meta_gradient_create_multi_horizontal (int width, int height,
|
||||
|
||||
g_return_val_if_fail (count > 2, NULL);
|
||||
|
||||
pixbuf = blank_pixbuf (width, height);
|
||||
pixbuf = blank_pixbuf (width, height, FALSE);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -526,7 +509,6 @@ meta_gradient_create_multi_horizontal (int width, int height,
|
||||
r = (long)(colors[0].red * 0xffffff);
|
||||
g = (long)(colors[0].green * 0xffffff);
|
||||
b = (long)(colors[0].blue * 0xffffff);
|
||||
a = (long)(colors[0].alpha * 0xffffff);
|
||||
|
||||
/* render the first line */
|
||||
for (i=1; i<count; i++)
|
||||
@@ -534,30 +516,25 @@ meta_gradient_create_multi_horizontal (int width, int height,
|
||||
dr = (int)((colors[i].red - colors[i-1].red) *0xffffff)/(int)width2;
|
||||
dg = (int)((colors[i].green - colors[i-1].green)*0xffffff)/(int)width2;
|
||||
db = (int)((colors[i].blue - colors[i-1].blue) *0xffffff)/(int)width2;
|
||||
da = (int)((colors[i].alpha - colors[i-1].alpha) *0xffffff)/(int)width2;
|
||||
for (j=0; j<width2; j++)
|
||||
{
|
||||
*ptr++ = (unsigned char)(r>>16);
|
||||
*ptr++ = (unsigned char)(g>>16);
|
||||
*ptr++ = (unsigned char)(b>>16);
|
||||
*ptr++ = (unsigned char)(a>>16);
|
||||
r += dr;
|
||||
g += dg;
|
||||
b += db;
|
||||
a += da;
|
||||
k++;
|
||||
}
|
||||
r = (long)(colors[i].red * 0xffffff);
|
||||
g = (long)(colors[i].green * 0xffffff);
|
||||
b = (long)(colors[i].blue * 0xffffff);
|
||||
a = (long)(colors[i].alpha * 0xffffff);
|
||||
}
|
||||
for (j=k; j<width; j++)
|
||||
{
|
||||
*ptr++ = (unsigned char)(r>>16);
|
||||
*ptr++ = (unsigned char)(g>>16);
|
||||
*ptr++ = (unsigned char)(b>>16);
|
||||
*ptr++ = (unsigned char)(a>>16);
|
||||
}
|
||||
|
||||
/* copy the first line to the other lines */
|
||||
@@ -574,7 +551,7 @@ meta_gradient_create_multi_vertical (int width, int height,
|
||||
int count)
|
||||
{
|
||||
int i, j, k;
|
||||
long r, g, b, a, dr, dg, db, da;
|
||||
long r, g, b, dr, dg, db;
|
||||
GdkPixbuf *pixbuf;
|
||||
unsigned char *ptr, *tmp, *pixels;
|
||||
int height2;
|
||||
@@ -583,7 +560,7 @@ meta_gradient_create_multi_vertical (int width, int height,
|
||||
|
||||
g_return_val_if_fail (count > 2, NULL);
|
||||
|
||||
pixbuf = blank_pixbuf (width, height);
|
||||
pixbuf = blank_pixbuf (width, height, FALSE);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -604,38 +581,33 @@ meta_gradient_create_multi_vertical (int width, int height,
|
||||
r = (long)(colors[0].red * 0xffffff);
|
||||
g = (long)(colors[0].green * 0xffffff);
|
||||
b = (long)(colors[0].blue * 0xffffff);
|
||||
a = (long)(colors[0].alpha * 0xffffff);
|
||||
|
||||
for (i=1; i<count; i++)
|
||||
{
|
||||
dr = (int)((colors[i].red - colors[i-1].red) *0xffffff)/(int)height2;
|
||||
dg = (int)((colors[i].green - colors[i-1].green)*0xffffff)/(int)height2;
|
||||
db = (int)((colors[i].blue - colors[i-1].blue) *0xffffff)/(int)height2;
|
||||
da = (int)((colors[i].alpha - colors[i-1].alpha) *0xffffff)/(int)height2;
|
||||
|
||||
for (j=0; j<height2; j++)
|
||||
{
|
||||
ptr[0] = (unsigned char)(r>>16);
|
||||
ptr[1] = (unsigned char)(g>>16);
|
||||
ptr[2] = (unsigned char)(b>>16);
|
||||
ptr[3] = (unsigned char)(a>>16);
|
||||
|
||||
for (x=1; x <= width/2; x *= 2)
|
||||
memcpy (&(ptr[x*4]), ptr, x*4);
|
||||
memcpy (&(ptr[x*4]), ptr, (width - x)*4);
|
||||
memcpy (&(ptr[x*3]), ptr, x*3);
|
||||
memcpy (&(ptr[x*3]), ptr, (width - x)*3);
|
||||
|
||||
ptr += rowstride;
|
||||
|
||||
r += dr;
|
||||
g += dg;
|
||||
b += db;
|
||||
a += da;
|
||||
k++;
|
||||
}
|
||||
r = (long)(colors[i].red * 0xffffff);
|
||||
g = (long)(colors[i].green * 0xffffff);
|
||||
b = (long)(colors[i].blue * 0xffffff);
|
||||
a = (long)(colors[i].alpha * 0xffffff);
|
||||
}
|
||||
|
||||
if (k<height)
|
||||
@@ -645,11 +617,10 @@ meta_gradient_create_multi_vertical (int width, int height,
|
||||
ptr[0] = (unsigned char) (r>>16);
|
||||
ptr[1] = (unsigned char) (g>>16);
|
||||
ptr[2] = (unsigned char) (b>>16);
|
||||
ptr[3] = (unsigned char) (a>>16);
|
||||
|
||||
for (x=1; x <= width/2; x *= 2)
|
||||
memcpy (&(ptr[x*4]), ptr, x*4);
|
||||
memcpy (&(ptr[x*4]), ptr, (width - x)*4);
|
||||
memcpy (&(ptr[x*3]), ptr, x*3);
|
||||
memcpy (&(ptr[x*3]), ptr, (width - x)*3);
|
||||
|
||||
ptr += rowstride;
|
||||
|
||||
|
@@ -163,7 +163,6 @@ color_composite (const GdkRGBA *bg,
|
||||
color->red = color->red + (fg->red - color->red) * alpha;
|
||||
color->green = color->green + (fg->green - color->green) * alpha;
|
||||
color->blue = color->blue + (fg->blue - color->blue) * alpha;
|
||||
color->alpha = color->alpha + (fg->alpha - color->alpha) * alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4139,6 +4138,18 @@ meta_draw_op_list_draw_with_style (const MetaDrawOpList *op_list,
|
||||
|
||||
fill_env (&env, info, rect);
|
||||
|
||||
/* FIXME this can be optimized, potentially a lot, by
|
||||
* compressing multiple ops when possible. For example,
|
||||
* anything convertible to a pixbuf can be composited
|
||||
* client-side, and putting a color tint over a pixbuf
|
||||
* can be done without creating the solid-color pixbuf.
|
||||
*
|
||||
* To implement this my plan is to have the idea of a
|
||||
* compiled draw op (with the string expressions already
|
||||
* evaluated), we make an array of those, and then fold
|
||||
* adjacent items when possible.
|
||||
*/
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
for (i = 0; i < op_list->n_ops; i++)
|
||||
@@ -6343,7 +6354,6 @@ gtk_style_shade (GdkRGBA *a,
|
||||
b->red = red;
|
||||
b->green = green;
|
||||
b->blue = blue;
|
||||
b->alpha = a->alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
|
132
src/ui/ui.c
132
src/ui/ui.c
@@ -26,6 +26,7 @@
|
||||
#include <meta/util.h>
|
||||
#include "core.h"
|
||||
#include "theme-private.h"
|
||||
#include "x11/events.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -83,31 +84,6 @@ is_input_event (XEvent *event)
|
||||
event->xcookie.extension == display->xinput_opcode);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_interesting_input_event (XEvent *event)
|
||||
{
|
||||
XIEvent *input_event;
|
||||
|
||||
if (!is_input_event (event))
|
||||
return FALSE;
|
||||
|
||||
input_event = (XIEvent *) event->xcookie.data;
|
||||
switch (input_event->evtype)
|
||||
{
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
case XI_Motion:
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchUpdate:
|
||||
case XI_TouchEnd:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* We do some of our event handling in frames.c, which expects
|
||||
* GDK events delivered by GTK+. However, since the transition to
|
||||
* client side windows, we can't let GDK see button events, since the
|
||||
@@ -123,7 +99,7 @@ is_interesting_input_event (XEvent *event)
|
||||
* use more fields, more fields need to be filled out below.
|
||||
*/
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
maybe_redirect_mouse_event (XEvent *xevent)
|
||||
{
|
||||
GdkDisplay *gdisplay;
|
||||
@@ -137,6 +113,9 @@ maybe_redirect_mouse_event (XEvent *xevent)
|
||||
XIDeviceEvent *xev_d = NULL;
|
||||
XIEnterEvent *xev_e = NULL;
|
||||
|
||||
if (!is_input_event (xevent))
|
||||
return FALSE;
|
||||
|
||||
xev = (XIEvent *) xevent->xcookie.data;
|
||||
|
||||
switch (xev->evtype)
|
||||
@@ -153,18 +132,17 @@ maybe_redirect_mouse_event (XEvent *xevent)
|
||||
window = xev_e->event;
|
||||
break;
|
||||
default:
|
||||
/* Not interested in this event. */
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdisplay = gdk_x11_lookup_xdisplay (xev->display);
|
||||
ui = g_object_get_data (G_OBJECT (gdisplay), "meta-ui");
|
||||
if (!ui)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
gdk_window = gdk_x11_window_lookup_for_display (gdisplay, window);
|
||||
if (gdk_window == NULL)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
gmanager = gdk_display_get_device_manager (gdisplay);
|
||||
gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);
|
||||
@@ -221,13 +199,13 @@ maybe_redirect_mouse_event (XEvent *xevent)
|
||||
gevent->button.y = xev_d->event_y;
|
||||
gevent->button.x_root = xev_d->root_x;
|
||||
gevent->button.y_root = xev_d->root_y;
|
||||
|
||||
break;
|
||||
case XI_Motion:
|
||||
gevent = gdk_event_new (GDK_MOTION_NOTIFY);
|
||||
gevent->motion.type = GDK_MOTION_NOTIFY;
|
||||
gevent->motion.window = g_object_ref (gdk_window);
|
||||
gevent->motion.time = xev_d->time;
|
||||
gevent->motion.x = xev_d->event_x;
|
||||
gevent->motion.y = xev_d->event_y;
|
||||
gevent->motion.x_root = xev_d->root_x;
|
||||
gevent->motion.y_root = xev_d->root_y;
|
||||
|
||||
@@ -238,7 +216,6 @@ maybe_redirect_mouse_event (XEvent *xevent)
|
||||
case XI_Leave:
|
||||
gevent = gdk_event_new (xev_e->evtype == XI_Enter ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY);
|
||||
gevent->crossing.window = g_object_ref (gdk_window);
|
||||
gevent->crossing.time = xev_e->time;
|
||||
gevent->crossing.x = xev_e->event_x;
|
||||
gevent->crossing.y = xev_e->event_y;
|
||||
break;
|
||||
@@ -251,20 +228,15 @@ maybe_redirect_mouse_event (XEvent *xevent)
|
||||
gdk_event_set_device (gevent, gdevice);
|
||||
gtk_main_do_event (gevent);
|
||||
gdk_event_free (gevent);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GdkFilterReturn
|
||||
ui_filter_func (GdkXEvent *xevent,
|
||||
GdkEvent *event,
|
||||
static void
|
||||
ui_filter_func (gpointer xevent,
|
||||
gpointer data)
|
||||
{
|
||||
if (is_interesting_input_event (xevent))
|
||||
{
|
||||
maybe_redirect_mouse_event (xevent);
|
||||
return GDK_FILTER_REMOVE;
|
||||
}
|
||||
else
|
||||
return GDK_FILTER_CONTINUE;
|
||||
maybe_redirect_mouse_event (xevent);
|
||||
}
|
||||
|
||||
MetaUI*
|
||||
@@ -290,7 +262,7 @@ meta_ui_new (Display *xdisplay,
|
||||
*/
|
||||
gtk_widget_show (GTK_WIDGET (ui->frames));
|
||||
|
||||
gdk_window_add_filter (NULL, ui_filter_func, NULL);
|
||||
meta_display_events_x11_add_func (ui_filter_func, NULL);
|
||||
|
||||
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui);
|
||||
|
||||
@@ -307,7 +279,7 @@ meta_ui_free (MetaUI *ui)
|
||||
gdisplay = gdk_x11_lookup_xdisplay (ui->xdisplay);
|
||||
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", NULL);
|
||||
|
||||
gdk_window_remove_filter (NULL, ui_filter_func, NULL);
|
||||
meta_display_events_x11_add_func (ui_filter_func, NULL);
|
||||
|
||||
g_free (ui);
|
||||
}
|
||||
@@ -555,6 +527,76 @@ meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
|
||||
return retval;
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
meta_ui_get_default_window_icon (MetaUI *ui)
|
||||
{
|
||||
static GdkPixbuf *default_icon = NULL;
|
||||
|
||||
if (default_icon == NULL)
|
||||
{
|
||||
GtkIconTheme *theme;
|
||||
gboolean icon_exists;
|
||||
|
||||
theme = gtk_icon_theme_get_default ();
|
||||
|
||||
icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
|
||||
|
||||
if (icon_exists)
|
||||
default_icon = gtk_icon_theme_load_icon (theme,
|
||||
META_DEFAULT_ICON_NAME,
|
||||
META_ICON_WIDTH,
|
||||
0,
|
||||
NULL);
|
||||
else
|
||||
default_icon = gtk_icon_theme_load_icon (theme,
|
||||
"image-missing",
|
||||
META_ICON_WIDTH,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
g_assert (default_icon);
|
||||
}
|
||||
|
||||
g_object_ref (G_OBJECT (default_icon));
|
||||
|
||||
return default_icon;
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
meta_ui_get_default_mini_icon (MetaUI *ui)
|
||||
{
|
||||
static GdkPixbuf *default_icon = NULL;
|
||||
|
||||
if (default_icon == NULL)
|
||||
{
|
||||
GtkIconTheme *theme;
|
||||
gboolean icon_exists;
|
||||
|
||||
theme = gtk_icon_theme_get_default ();
|
||||
|
||||
icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
|
||||
|
||||
if (icon_exists)
|
||||
default_icon = gtk_icon_theme_load_icon (theme,
|
||||
META_DEFAULT_ICON_NAME,
|
||||
META_MINI_ICON_WIDTH,
|
||||
0,
|
||||
NULL);
|
||||
else
|
||||
default_icon = gtk_icon_theme_load_icon (theme,
|
||||
"image-missing",
|
||||
META_MINI_ICON_WIDTH,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
g_assert (default_icon);
|
||||
}
|
||||
|
||||
g_object_ref (G_OBJECT (default_icon));
|
||||
|
||||
return default_icon;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_ui_window_should_not_cause_focus (Display *xdisplay,
|
||||
Window xwindow)
|
||||
|
@@ -121,6 +121,9 @@ GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
GdkPixbuf* meta_ui_get_default_window_icon (MetaUI *ui);
|
||||
GdkPixbuf* meta_ui_get_default_mini_icon (MetaUI *ui);
|
||||
|
||||
gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay,
|
||||
Window xwindow);
|
||||
|
||||
|
@@ -35,25 +35,6 @@
|
||||
#include "meta-wayland-pointer.h"
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
MetaWaylandDataSource *source;
|
||||
struct wl_listener source_destroy_listener;
|
||||
} MetaWaylandDataOffer;
|
||||
|
||||
struct _MetaWaylandDataSource
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
struct wl_array mime_types;
|
||||
};
|
||||
|
||||
static void
|
||||
unbind_resource (struct wl_resource *resource)
|
||||
{
|
||||
wl_list_remove (wl_resource_get_link (resource));
|
||||
}
|
||||
|
||||
static void
|
||||
data_offer_accept (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
@@ -198,8 +179,7 @@ drag_grab_focus (MetaWaylandPointerGrab *grab,
|
||||
{
|
||||
MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab;
|
||||
MetaWaylandSeat *seat = drag_grab->seat;
|
||||
struct wl_client *client;
|
||||
struct wl_resource *data_device_resource, *offer = NULL;
|
||||
struct wl_resource *resource, *offer = NULL;
|
||||
struct wl_display *display;
|
||||
guint32 serial;
|
||||
wl_fixed_t sx, sy;
|
||||
@@ -222,28 +202,28 @@ drag_grab_focus (MetaWaylandPointerGrab *grab,
|
||||
wl_resource_get_client (surface->resource) != drag_grab->drag_client)
|
||||
return;
|
||||
|
||||
client = wl_resource_get_client (surface->resource);
|
||||
|
||||
data_device_resource = wl_resource_find_for_client (&seat->data_device.resource_list, client);
|
||||
if (!data_device_resource)
|
||||
resource =
|
||||
wl_resource_find_for_client (&seat->data_device_resource_list,
|
||||
wl_resource_get_client (surface->resource));
|
||||
if (!resource)
|
||||
return;
|
||||
|
||||
display = wl_client_get_display (client);
|
||||
display = wl_client_get_display (wl_resource_get_client (resource));
|
||||
serial = wl_display_next_serial (display);
|
||||
|
||||
if (drag_grab->drag_data_source)
|
||||
offer = meta_wayland_data_source_send_offer (drag_grab->drag_data_source,
|
||||
data_device_resource);
|
||||
resource);
|
||||
|
||||
meta_wayland_pointer_get_relative_coordinates (grab->pointer, surface, &sx, &sy);
|
||||
wl_data_device_send_enter (data_device_resource, serial, surface->resource,
|
||||
wl_data_device_send_enter (resource, serial, surface->resource,
|
||||
sx, sy, offer);
|
||||
|
||||
drag_grab->drag_focus = surface;
|
||||
|
||||
drag_grab->drag_focus_data_device = data_device_resource;
|
||||
drag_grab->drag_focus_data_device = resource;
|
||||
drag_grab->drag_focus_listener.notify = destroy_drag_focus;
|
||||
wl_resource_add_destroy_listener (data_device_resource, &drag_grab->drag_focus_listener);
|
||||
wl_resource_add_destroy_listener (resource, &drag_grab->drag_focus_listener);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -332,8 +312,7 @@ data_device_start_drag (struct wl_client *client,
|
||||
struct wl_resource *origin_resource,
|
||||
struct wl_resource *icon_resource, guint32 serial)
|
||||
{
|
||||
MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
|
||||
MetaWaylandDragGrab *drag_grab;
|
||||
|
||||
if ((seat->pointer.button_count == 0 ||
|
||||
@@ -378,67 +357,68 @@ data_device_start_drag (struct wl_client *client,
|
||||
static void
|
||||
destroy_selection_data_source (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaWaylandDataDevice *data_device = wl_container_of (listener, data_device, selection_data_source_listener);
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
struct wl_resource *data_device_resource;
|
||||
MetaWaylandSeat *seat =
|
||||
wl_container_of (listener, seat, selection_data_source_listener);
|
||||
struct wl_resource *data_device;
|
||||
struct wl_client *focus_client = NULL;
|
||||
|
||||
data_device->selection_data_source = NULL;
|
||||
seat->selection_data_source = NULL;
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (&seat->keyboard);
|
||||
if (focus_client)
|
||||
{
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
wl_data_device_send_selection (data_device_resource, NULL);
|
||||
data_device = wl_resource_find_for_client (&seat->data_device_resource_list, focus_client);
|
||||
if (data_device)
|
||||
wl_data_device_send_selection (data_device, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
|
||||
MetaWaylandDataSource *source,
|
||||
guint32 serial)
|
||||
meta_wayland_seat_set_selection (MetaWaylandSeat *seat,
|
||||
MetaWaylandDataSource *source,
|
||||
guint32 serial)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
struct wl_resource *data_device_resource, *offer;
|
||||
struct wl_resource *data_device, *offer;
|
||||
struct wl_client *focus_client;
|
||||
|
||||
if (data_device->selection_data_source &&
|
||||
data_device->selection_serial - serial < UINT32_MAX / 2)
|
||||
if (seat->selection_data_source &&
|
||||
seat->selection_serial - serial < UINT32_MAX / 2)
|
||||
return;
|
||||
|
||||
if (data_device->selection_data_source)
|
||||
if (seat->selection_data_source)
|
||||
{
|
||||
wl_data_source_send_cancelled (data_device->selection_data_source->resource);
|
||||
wl_list_remove (&data_device->selection_data_source_listener.link);
|
||||
data_device->selection_data_source = NULL;
|
||||
wl_data_source_send_cancelled (seat->selection_data_source->resource);
|
||||
wl_list_remove (&seat->selection_data_source_listener.link);
|
||||
seat->selection_data_source = NULL;
|
||||
}
|
||||
|
||||
data_device->selection_data_source = source;
|
||||
data_device->selection_serial = serial;
|
||||
seat->selection_data_source = source;
|
||||
seat->selection_serial = serial;
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (&seat->keyboard);
|
||||
if (focus_client)
|
||||
{
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
data_device = wl_resource_find_for_client (&seat->data_device_resource_list, focus_client);
|
||||
if (data_device)
|
||||
{
|
||||
if (data_device->selection_data_source)
|
||||
if (seat->selection_data_source)
|
||||
{
|
||||
offer = meta_wayland_data_source_send_offer (data_device->selection_data_source, data_device_resource);
|
||||
wl_data_device_send_selection (data_device_resource, offer);
|
||||
offer = meta_wayland_data_source_send_offer (seat->selection_data_source, data_device);
|
||||
wl_data_device_send_selection (data_device, offer);
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_data_device_send_selection (data_device_resource, NULL);
|
||||
wl_data_device_send_selection (data_device, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (source)
|
||||
{
|
||||
data_device->selection_data_source_listener.notify = destroy_selection_data_source;
|
||||
wl_resource_add_destroy_listener (source->resource, &data_device->selection_data_source_listener);
|
||||
seat->selection_data_source_listener.notify =
|
||||
destroy_selection_data_source;
|
||||
wl_resource_add_destroy_listener (source->resource,
|
||||
&seat->selection_data_source_listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,16 +428,13 @@ data_device_set_selection (struct wl_client *client,
|
||||
struct wl_resource *source_resource,
|
||||
guint32 serial)
|
||||
{
|
||||
MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource);
|
||||
MetaWaylandDataSource *source;
|
||||
|
||||
if (!source_resource)
|
||||
return;
|
||||
|
||||
source = wl_resource_get_user_data (source_resource);
|
||||
|
||||
/* FIXME: Store serial and check against incoming serial here. */
|
||||
meta_wayland_data_device_set_selection (data_device, source, serial);
|
||||
meta_wayland_seat_set_selection (wl_resource_get_user_data (resource),
|
||||
wl_resource_get_user_data (source_resource),
|
||||
serial);
|
||||
}
|
||||
|
||||
static const struct wl_data_device_interface data_device_interface = {
|
||||
@@ -493,18 +470,25 @@ create_data_source (struct wl_client *client,
|
||||
wl_array_init (&source->mime_types);
|
||||
}
|
||||
|
||||
static void
|
||||
unbind_data_device (struct wl_resource *resource)
|
||||
{
|
||||
wl_list_remove (wl_resource_get_link (resource));
|
||||
}
|
||||
|
||||
static void
|
||||
get_data_device (struct wl_client *client,
|
||||
struct wl_resource *manager_resource,
|
||||
guint32 id, struct wl_resource *seat_resource)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||
struct wl_resource *cr;
|
||||
struct wl_resource *resource;
|
||||
|
||||
cr = wl_resource_create (client, &wl_data_device_interface,
|
||||
MIN (META_WL_DATA_DEVICE_VERSION, wl_resource_get_version (manager_resource)), id);
|
||||
wl_resource_set_implementation (cr, &data_device_interface, &seat->data_device, unbind_resource);
|
||||
wl_list_insert (&seat->data_device.resource_list, wl_resource_get_link (cr));
|
||||
resource = wl_resource_create (client, &wl_data_device_interface,
|
||||
MIN (META_WL_DATA_DEVICE_VERSION,
|
||||
wl_resource_get_version (manager_resource)), id);
|
||||
wl_resource_set_implementation (resource, &data_device_interface, seat, unbind_data_device);
|
||||
wl_list_insert (&seat->data_device_resource_list, wl_resource_get_link (resource));
|
||||
}
|
||||
|
||||
static const struct wl_data_device_manager_interface manager_interface = {
|
||||
@@ -534,31 +518,24 @@ meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor)
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_device_init (MetaWaylandDataDevice *data_device)
|
||||
meta_wayland_data_device_set_keyboard_focus (MetaWaylandSeat *seat)
|
||||
{
|
||||
wl_list_init (&data_device->resource_list);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
struct wl_client *focus_client;
|
||||
struct wl_resource *data_device_resource, *offer;
|
||||
struct wl_resource *data_device, *offer;
|
||||
MetaWaylandDataSource *source;
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (&seat->keyboard);
|
||||
if (!focus_client)
|
||||
return;
|
||||
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
||||
if (!data_device_resource)
|
||||
data_device = wl_resource_find_for_client (&seat->data_device_resource_list, focus_client);
|
||||
if (!data_device)
|
||||
return;
|
||||
|
||||
source = data_device->selection_data_source;
|
||||
source = seat->selection_data_source;
|
||||
if (source)
|
||||
{
|
||||
offer = meta_wayland_data_source_send_offer (source, data_device_resource);
|
||||
wl_data_device_send_selection (data_device_resource, offer);
|
||||
offer = meta_wayland_data_source_send_offer (source, data_device);
|
||||
wl_data_device_send_selection (data_device, offer);
|
||||
}
|
||||
}
|
||||
|
@@ -25,20 +25,10 @@
|
||||
|
||||
#include <wayland-server.h>
|
||||
|
||||
#include "meta-wayland-types.h"
|
||||
|
||||
struct _MetaWaylandDataDevice
|
||||
{
|
||||
uint32_t selection_serial;
|
||||
MetaWaylandDataSource *selection_data_source;
|
||||
struct wl_listener selection_data_source_listener;
|
||||
struct wl_list resource_list;
|
||||
};
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
void meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor);
|
||||
|
||||
void meta_wayland_data_device_init (MetaWaylandDataDevice *data_device);
|
||||
|
||||
void meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device);
|
||||
void meta_wayland_data_device_set_keyboard_focus (MetaWaylandSeat *seat);
|
||||
|
||||
#endif /* META_WAYLAND_DATA_DEVICE_H */
|
||||
|
@@ -301,7 +301,6 @@ meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info)
|
||||
void
|
||||
meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard)
|
||||
{
|
||||
meta_wayland_keyboard_set_focus (keyboard, NULL);
|
||||
meta_wayland_xkb_info_destroy (&keyboard->xkb_info);
|
||||
xkb_context_unref (keyboard->xkb_context);
|
||||
|
||||
@@ -550,7 +549,7 @@ meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard,
|
||||
|
||||
cr = wl_resource_create (client, &wl_keyboard_interface,
|
||||
MIN (META_WL_KEYBOARD_VERSION, wl_resource_get_version (seat_resource)), id);
|
||||
wl_resource_set_implementation (cr, &keyboard_interface, keyboard, unbind_resource);
|
||||
wl_resource_set_implementation (cr, NULL, keyboard, unbind_resource);
|
||||
wl_list_insert (&keyboard->resource_list, wl_resource_get_link (cr));
|
||||
|
||||
wl_keyboard_send_keymap (cr,
|
||||
|
@@ -168,20 +168,12 @@ wayland_output_destroy_notify (gpointer data)
|
||||
g_slice_free (MetaWaylandOutput, wayland_output);
|
||||
}
|
||||
|
||||
static inline enum wl_output_transform
|
||||
wl_output_transform_from_meta_monitor_transform (MetaMonitorTransform transform)
|
||||
{
|
||||
/* The enums are the same. */
|
||||
return (enum wl_output_transform) transform;
|
||||
}
|
||||
|
||||
static void
|
||||
wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
|
||||
MetaOutput *output)
|
||||
{
|
||||
GList *iter;
|
||||
guint mode_flags;
|
||||
enum wl_output_transform wl_transform = wl_output_transform_from_meta_monitor_transform (output->crtc->transform);
|
||||
|
||||
g_assert (output->crtc->current_mode != NULL);
|
||||
|
||||
@@ -195,7 +187,7 @@ wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
|
||||
|
||||
if (wayland_output->x != output->crtc->rect.x ||
|
||||
wayland_output->y != output->crtc->rect.y ||
|
||||
wayland_output->transform != wl_transform)
|
||||
wayland_output->transform != output->crtc->transform)
|
||||
{
|
||||
wl_resource_post_event (resource,
|
||||
WL_OUTPUT_GEOMETRY,
|
||||
@@ -206,7 +198,7 @@ wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
|
||||
output->subpixel_order,
|
||||
output->vendor,
|
||||
output->product,
|
||||
wl_transform);
|
||||
output->crtc->transform);
|
||||
}
|
||||
|
||||
wl_resource_post_event (resource,
|
||||
@@ -222,7 +214,7 @@ wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
|
||||
wayland_output->output = output;
|
||||
wayland_output->x = output->crtc->rect.x;
|
||||
wayland_output->y = output->crtc->rect.y;
|
||||
wayland_output->transform = wl_transform;
|
||||
wayland_output->transform = output->crtc->transform;
|
||||
}
|
||||
|
||||
static GHashTable *
|
||||
@@ -244,15 +236,15 @@ meta_wayland_compositor_update_outputs (MetaWaylandCompositor *compositor,
|
||||
/* wayland does not expose disabled outputs */
|
||||
if (output->crtc == NULL)
|
||||
{
|
||||
g_hash_table_remove (compositor->outputs, GSIZE_TO_POINTER (output->winsys_id));
|
||||
g_hash_table_remove (compositor->outputs, GSIZE_TO_POINTER (output->output_id));
|
||||
continue;
|
||||
}
|
||||
|
||||
wayland_output = g_hash_table_lookup (compositor->outputs, GSIZE_TO_POINTER (output->winsys_id));
|
||||
wayland_output = g_hash_table_lookup (compositor->outputs, GSIZE_TO_POINTER (output->output_id));
|
||||
|
||||
if (wayland_output)
|
||||
{
|
||||
g_hash_table_steal (compositor->outputs, GSIZE_TO_POINTER (output->winsys_id));
|
||||
g_hash_table_steal (compositor->outputs, GSIZE_TO_POINTER (output->output_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -264,7 +256,7 @@ meta_wayland_compositor_update_outputs (MetaWaylandCompositor *compositor,
|
||||
}
|
||||
|
||||
wayland_output_update_for_output (wayland_output, output);
|
||||
g_hash_table_insert (new_table, GSIZE_TO_POINTER (output->winsys_id), wayland_output);
|
||||
g_hash_table_insert (new_table, GSIZE_TO_POINTER (output->output_id), wayland_output);
|
||||
}
|
||||
|
||||
g_hash_table_destroy (compositor->outputs);
|
||||
|
@@ -207,14 +207,11 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer,
|
||||
|
||||
manager = clutter_device_manager_get_default ();
|
||||
pointer->device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
|
||||
|
||||
pointer->cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_release (MetaWaylandPointer *pointer)
|
||||
{
|
||||
meta_wayland_pointer_set_focus (pointer, NULL);
|
||||
set_cursor_surface (pointer, NULL);
|
||||
}
|
||||
|
||||
@@ -816,7 +813,7 @@ meta_wayland_pointer_can_grab_surface (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface,
|
||||
uint32_t serial)
|
||||
{
|
||||
return (pointer->button_count > 0 &&
|
||||
return (pointer->button_count == 0 &&
|
||||
pointer->grab_serial == serial &&
|
||||
pointer->focus_surface == surface);
|
||||
}
|
||||
|
@@ -50,6 +50,10 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
struct wl_list link;
|
||||
|
||||
/* Pointer back to the compositor */
|
||||
MetaWaylandCompositor *compositor;
|
||||
|
||||
struct wl_resource *resource;
|
||||
} MetaWaylandFrameCallback;
|
||||
|
||||
@@ -71,8 +75,10 @@ struct _MetaWaylandCompositor
|
||||
{
|
||||
struct wl_display *wayland_display;
|
||||
char *display_name;
|
||||
struct wl_event_loop *wayland_loop;
|
||||
ClutterActor *stage;
|
||||
GHashTable *outputs;
|
||||
GSource *wayland_event_source;
|
||||
struct wl_list frame_callbacks;
|
||||
|
||||
MetaXWaylandManager xwayland_manager;
|
||||
|
@@ -25,7 +25,6 @@
|
||||
|
||||
#include "meta-wayland-private.h"
|
||||
#include "meta-wayland-versions.h"
|
||||
#include "meta-wayland-data-device.h"
|
||||
|
||||
static void
|
||||
unbind_resource (struct wl_resource *resource)
|
||||
@@ -100,12 +99,15 @@ meta_wayland_seat_new (struct wl_display *display)
|
||||
{
|
||||
MetaWaylandSeat *seat = g_new0 (MetaWaylandSeat, 1);
|
||||
|
||||
seat->selection_data_source = NULL;
|
||||
wl_list_init (&seat->base_resource_list);
|
||||
wl_list_init (&seat->data_device_resource_list);
|
||||
|
||||
meta_wayland_pointer_init (&seat->pointer, display);
|
||||
meta_wayland_keyboard_init (&seat->keyboard, display);
|
||||
meta_wayland_touch_init (&seat->touch, display);
|
||||
meta_wayland_data_device_init (&seat->data_device);
|
||||
|
||||
seat->display = display;
|
||||
|
||||
wl_global_create (display, &wl_seat_interface, META_WL_SEAT_VERSION, seat, bind_seat);
|
||||
|
||||
@@ -191,14 +193,6 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat)
|
||||
meta_wayland_pointer_repick (&seat->pointer);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_seat_set_input_focus (MetaWaylandSeat *seat,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
meta_wayland_keyboard_set_focus (&seat->keyboard, surface);
|
||||
meta_wayland_data_device_set_keyboard_focus (&seat->data_device);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat)
|
||||
{
|
||||
|
@@ -26,19 +26,37 @@
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "meta-wayland-types.h"
|
||||
#include "meta-wayland-pointer.h"
|
||||
#include "meta-wayland-keyboard.h"
|
||||
#include "meta-wayland-pointer.h"
|
||||
#include "meta-wayland-touch.h"
|
||||
#include "meta-wayland-data-device.h"
|
||||
|
||||
struct _MetaWaylandDataOffer
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
MetaWaylandDataSource *source;
|
||||
struct wl_listener source_destroy_listener;
|
||||
};
|
||||
|
||||
struct _MetaWaylandDataSource
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
struct wl_array mime_types;
|
||||
};
|
||||
|
||||
struct _MetaWaylandSeat
|
||||
{
|
||||
struct wl_list base_resource_list;
|
||||
|
||||
uint32_t selection_serial;
|
||||
MetaWaylandDataSource *selection_data_source;
|
||||
struct wl_listener selection_data_source_listener;
|
||||
|
||||
struct wl_list data_device_resource_list;
|
||||
MetaWaylandPointer pointer;
|
||||
MetaWaylandKeyboard keyboard;
|
||||
MetaWaylandTouch touch;
|
||||
MetaWaylandDataDevice data_device;
|
||||
|
||||
struct wl_display *display;
|
||||
};
|
||||
|
||||
void meta_wayland_seat_init (MetaWaylandCompositor *compositor);
|
||||
@@ -51,9 +69,6 @@ void meta_wayland_seat_update (MetaWaylandSeat *seat,
|
||||
gboolean meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event);
|
||||
|
||||
void meta_wayland_seat_set_input_focus (MetaWaylandSeat *seat,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_seat_repick (MetaWaylandSeat *seat);
|
||||
void meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat);
|
||||
|
||||
|
@@ -163,88 +163,33 @@ cursor_surface_commit (MetaWaylandSurface *surface,
|
||||
}
|
||||
|
||||
static void
|
||||
calculate_surface_window_geometry (MetaWaylandSurface *surface,
|
||||
MetaRectangle *total_geometry,
|
||||
float parent_x,
|
||||
float parent_y)
|
||||
{
|
||||
ClutterActor *surface_actor = CLUTTER_ACTOR (surface->surface_actor);
|
||||
MetaRectangle geom;
|
||||
float x, y;
|
||||
GList *l;
|
||||
|
||||
/* Unmapped surfaces don't count. */
|
||||
if (!CLUTTER_ACTOR_IS_VISIBLE (surface_actor))
|
||||
return;
|
||||
|
||||
/* XXX: Is there a better way to do this using Clutter APIs? */
|
||||
clutter_actor_get_position (surface_actor, &x, &y);
|
||||
|
||||
geom.x = parent_x + x;
|
||||
geom.y = parent_x + y;
|
||||
geom.width = cogl_texture_get_width (surface->buffer->texture);
|
||||
geom.height = cogl_texture_get_height (surface->buffer->texture);
|
||||
|
||||
meta_rectangle_union (total_geometry, &geom, total_geometry);
|
||||
|
||||
for (l = surface->subsurfaces; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWaylandSurface *subsurface = l->data;
|
||||
calculate_surface_window_geometry (subsurface, total_geometry, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
toplevel_surface_commit (MetaWaylandSurface *surface,
|
||||
toplevel_surface_commit (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWindow *window = surface->window;
|
||||
|
||||
/* Sanity check. */
|
||||
if (surface->buffer == NULL)
|
||||
if (pending->newly_attached)
|
||||
{
|
||||
wl_resource_post_error (surface->resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"Cannot commit a NULL buffer to an xdg_surface");
|
||||
return;
|
||||
MetaWindow *window = surface->window;
|
||||
MetaWaylandBuffer *buffer = pending->buffer;
|
||||
|
||||
meta_window_set_surface_mapped (window, buffer != NULL);
|
||||
/* We resize X based surfaces according to X events */
|
||||
if (buffer != NULL && window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
||||
{
|
||||
int new_width, new_height;
|
||||
|
||||
new_width = cogl_texture_get_width (buffer->texture);
|
||||
new_height = cogl_texture_get_height (buffer->texture);
|
||||
|
||||
if (new_width != window->rect.width ||
|
||||
new_height != window->rect.height ||
|
||||
pending->dx != 0 ||
|
||||
pending->dy != 0)
|
||||
meta_window_wayland_move_resize (window, new_width, new_height, pending->dx, pending->dy);
|
||||
}
|
||||
}
|
||||
|
||||
/* We resize X based surfaces according to X events */
|
||||
if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
||||
{
|
||||
MetaRectangle geom;
|
||||
|
||||
if (pending->has_new_geometry)
|
||||
{
|
||||
/* If we have new geometry, use it. */
|
||||
geom = pending->new_geometry;
|
||||
surface->has_set_geometry = TRUE;
|
||||
}
|
||||
else if (!surface->has_set_geometry)
|
||||
{
|
||||
/* If the surface has never set any geometry, calculate
|
||||
* a default one unioning the surface and all subsurfaces together. */
|
||||
calculate_surface_window_geometry (surface, &geom, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, keep the geometry the same. */
|
||||
|
||||
/* XXX: We don't store the geometry in any consistent place
|
||||
* right now, so we can't re-fetch it. We should change
|
||||
* meta_window_wayland_move_resize. */
|
||||
|
||||
/* XXX: This is the common case. Recognize it to prevent
|
||||
* a warning. */
|
||||
if (pending->dx == 0 && pending->dy == 0)
|
||||
return;
|
||||
|
||||
g_warning ("XXX: Attach-initiated move without a new geometry. This is unimplemented right now.");
|
||||
return;
|
||||
}
|
||||
|
||||
meta_window_wayland_move_resize (window, geom, pending->dx, pending->dy);
|
||||
}
|
||||
if (pending->frame_extents_changed)
|
||||
meta_window_set_custom_frame_extents (surface->window, &pending->frame_extents);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -271,7 +216,7 @@ pending_state_init (MetaWaylandPendingState *state)
|
||||
state->buffer_destroy_listener.notify = surface_handle_pending_buffer_destroy;
|
||||
wl_list_init (&state->frame_callback_list);
|
||||
|
||||
state->has_new_geometry = FALSE;
|
||||
state->frame_extents_changed = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -317,18 +262,22 @@ static void
|
||||
subsurface_surface_commit (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaSurfaceActor *surface_actor = surface->surface_actor;
|
||||
float x, y;
|
||||
if (pending->newly_attached)
|
||||
{
|
||||
MetaSurfaceActor *surface_actor = surface->surface_actor;
|
||||
MetaWaylandBuffer *buffer = pending->buffer;
|
||||
float x, y;
|
||||
|
||||
if (surface->buffer != NULL)
|
||||
clutter_actor_show (CLUTTER_ACTOR (surface_actor));
|
||||
else
|
||||
clutter_actor_hide (CLUTTER_ACTOR (surface_actor));
|
||||
if (buffer != NULL)
|
||||
clutter_actor_show (CLUTTER_ACTOR (surface_actor));
|
||||
else
|
||||
clutter_actor_hide (CLUTTER_ACTOR (surface_actor));
|
||||
|
||||
clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
|
||||
x += pending->dx;
|
||||
y += pending->dy;
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y);
|
||||
clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
|
||||
x += pending->dx;
|
||||
y += pending->dy;
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -467,13 +416,16 @@ wl_surface_attach (struct wl_client *client,
|
||||
else
|
||||
buffer = NULL;
|
||||
|
||||
if (surface->buffer == buffer)
|
||||
return;
|
||||
|
||||
if (surface->pending.buffer)
|
||||
wl_list_remove (&surface->pending.buffer_destroy_listener.link);
|
||||
|
||||
surface->pending.newly_attached = TRUE;
|
||||
surface->pending.buffer = buffer;
|
||||
surface->pending.dx = dx;
|
||||
surface->pending.dy = dy;
|
||||
surface->pending.buffer = buffer;
|
||||
surface->pending.newly_attached = TRUE;
|
||||
|
||||
if (buffer)
|
||||
wl_signal_add (&buffer->destroy_signal,
|
||||
@@ -521,6 +473,7 @@ wl_surface_frame (struct wl_client *client,
|
||||
return;
|
||||
|
||||
callback = g_slice_new0 (MetaWaylandFrameCallback);
|
||||
callback->compositor = surface->compositor;
|
||||
callback->resource = wl_resource_create (client, &wl_callback_interface, META_WL_CALLBACK_VERSION, callback_id);
|
||||
wl_resource_set_implementation (callback->resource, NULL, callback, destroy_frame_callback);
|
||||
|
||||
@@ -780,6 +733,23 @@ xdg_surface_set_parent (struct wl_client *client,
|
||||
meta_window_set_transient_for (surface->window, transient_for);
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_surface_set_margin (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
int32_t left_margin,
|
||||
int32_t right_margin,
|
||||
int32_t top_margin,
|
||||
int32_t bottom_margin)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
|
||||
surface->pending.frame_extents_changed = TRUE;
|
||||
surface->pending.frame_extents.left = left_margin;
|
||||
surface->pending.frame_extents.right = right_margin;
|
||||
surface->pending.frame_extents.top = top_margin;
|
||||
surface->pending.frame_extents.bottom = bottom_margin;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_surface_set_title (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
@@ -805,8 +775,8 @@ xdg_surface_show_window_menu (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *seat_resource,
|
||||
uint32_t serial,
|
||||
int32_t x,
|
||||
int32_t y)
|
||||
uint32_t x,
|
||||
uint32_t y)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
@@ -910,20 +880,6 @@ xdg_surface_ack_configure (struct wl_client *client,
|
||||
* client gets the new state. */
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_surface_set_window_geometry (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
|
||||
surface->pending.has_new_geometry = TRUE;
|
||||
surface->pending.new_geometry.x = x;
|
||||
surface->pending.new_geometry.y = y;
|
||||
surface->pending.new_geometry.width = width;
|
||||
surface->pending.new_geometry.height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_surface_set_maximized (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
@@ -968,13 +924,13 @@ xdg_surface_set_minimized (struct wl_client *client,
|
||||
static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = {
|
||||
xdg_surface_destroy,
|
||||
xdg_surface_set_parent,
|
||||
xdg_surface_set_margin,
|
||||
xdg_surface_set_title,
|
||||
xdg_surface_set_app_id,
|
||||
xdg_surface_show_window_menu,
|
||||
xdg_surface_move,
|
||||
xdg_surface_resize,
|
||||
xdg_surface_ack_configure,
|
||||
xdg_surface_set_window_geometry,
|
||||
xdg_surface_set_maximized,
|
||||
xdg_surface_unset_maximized,
|
||||
xdg_surface_set_fullscreen,
|
||||
@@ -1116,17 +1072,20 @@ bind_xdg_shell (struct wl_client *client,
|
||||
guint32 version,
|
||||
guint32 id)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
XdgShell *xdg_shell;
|
||||
|
||||
if (version != META_XDG_SHELL_VERSION)
|
||||
if (version != 1)
|
||||
{
|
||||
g_warning ("using xdg-shell without stable version %d\n", META_XDG_SHELL_VERSION);
|
||||
g_warning ("using xdg-shell without stable version 1\n");
|
||||
return;
|
||||
}
|
||||
|
||||
xdg_shell = g_slice_new (XdgShell);
|
||||
|
||||
xdg_shell->resource = wl_resource_create (client, &xdg_shell_interface, META_XDG_SHELL_VERSION, id);
|
||||
resource = wl_resource_create (client, &xdg_shell_interface, 1, id);
|
||||
wl_resource_set_implementation (resource, &meta_wayland_xdg_shell_interface, data, NULL);
|
||||
xdg_shell->resource = wl_resource_create (client, &xdg_shell_interface, 1, id);
|
||||
wl_resource_set_implementation (xdg_shell->resource, &meta_wayland_xdg_shell_interface, data, NULL);
|
||||
|
||||
xdg_shell->client_destroy_listener.notify = xdg_shell_handle_client_destroy;
|
||||
@@ -1392,13 +1351,13 @@ gtk_surface_destructor (struct wl_resource *resource)
|
||||
|
||||
static void
|
||||
set_dbus_properties (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
const char *application_id,
|
||||
const char *app_menu_path,
|
||||
const char *menubar_path,
|
||||
const char *window_object_path,
|
||||
const char *application_object_path,
|
||||
const char *unique_bus_name)
|
||||
struct wl_resource *resource,
|
||||
const char *application_id,
|
||||
const char *app_menu_path,
|
||||
const char *menubar_path,
|
||||
const char *window_object_path,
|
||||
const char *application_object_path,
|
||||
const char *unique_bus_name)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
|
||||
@@ -1424,9 +1383,9 @@ static const struct gtk_surface_interface meta_wayland_gtk_surface_interface = {
|
||||
|
||||
static void
|
||||
get_gtk_surface (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
guint32 id,
|
||||
struct wl_resource *surface_resource)
|
||||
struct wl_resource *resource,
|
||||
guint32 id,
|
||||
struct wl_resource *surface_resource)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||
|
||||
@@ -1450,14 +1409,14 @@ static const struct gtk_shell_interface meta_wayland_gtk_shell_interface = {
|
||||
|
||||
static void
|
||||
bind_gtk_shell (struct wl_client *client,
|
||||
void *data,
|
||||
guint32 version,
|
||||
guint32 id)
|
||||
void *data,
|
||||
guint32 version,
|
||||
guint32 id)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, >k_shell_interface,
|
||||
MIN (META_GTK_SHELL_VERSION, version), id);
|
||||
MIN (META_GTK_SHELL_VERSION, version), id);
|
||||
wl_resource_set_implementation (resource, &meta_wayland_gtk_shell_interface, data, NULL);
|
||||
|
||||
/* FIXME: ask the plugin */
|
||||
@@ -1744,7 +1703,7 @@ bind_subcompositor (struct wl_client *client,
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, &wl_subcompositor_interface,
|
||||
MIN (META_WL_SUBCOMPOSITOR_VERSION, version), id);
|
||||
MIN (META_WL_SUBCOMPOSITOR_VERSION, version), id);
|
||||
wl_resource_set_implementation (resource, &meta_wayland_subcompositor_interface, data, NULL);
|
||||
}
|
||||
|
||||
@@ -1752,21 +1711,19 @@ void
|
||||
meta_wayland_shell_init (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
if (wl_global_create (compositor->wayland_display,
|
||||
&xdg_shell_interface,
|
||||
META_XDG_SHELL_VERSION,
|
||||
compositor, bind_xdg_shell) == NULL)
|
||||
&xdg_shell_interface, 1,
|
||||
compositor, bind_xdg_shell) == NULL)
|
||||
g_error ("Failed to register a global xdg-shell object");
|
||||
|
||||
if (wl_global_create (compositor->wayland_display,
|
||||
&wl_shell_interface,
|
||||
META_WL_SHELL_VERSION,
|
||||
compositor, bind_wl_shell) == NULL)
|
||||
&wl_shell_interface, 1,
|
||||
compositor, bind_wl_shell) == NULL)
|
||||
g_error ("Failed to register a global wl-shell object");
|
||||
|
||||
if (wl_global_create (compositor->wayland_display,
|
||||
>k_shell_interface,
|
||||
META_GTK_SHELL_VERSION,
|
||||
compositor, bind_gtk_shell) == NULL)
|
||||
>k_shell_interface,
|
||||
META_GTK_SHELL_VERSION,
|
||||
compositor, bind_gtk_shell) == NULL)
|
||||
g_error ("Failed to register a global gtk-shell object");
|
||||
|
||||
if (wl_global_create (compositor->wayland_display,
|
||||
@@ -1805,8 +1762,8 @@ fill_states (struct wl_array *states, MetaWindow *window)
|
||||
|
||||
void
|
||||
meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
|
||||
int new_width,
|
||||
int new_height)
|
||||
int new_width,
|
||||
int new_height)
|
||||
{
|
||||
if (surface->xdg_surface.resource)
|
||||
{
|
||||
|
@@ -61,8 +61,8 @@ typedef struct
|
||||
/* wl_surface.frame */
|
||||
struct wl_list frame_callback_list;
|
||||
|
||||
MetaRectangle new_geometry;
|
||||
gboolean has_new_geometry;
|
||||
gboolean frame_extents_changed;
|
||||
GtkBorder frame_extents;
|
||||
} MetaWaylandPendingState;
|
||||
|
||||
typedef struct
|
||||
@@ -109,8 +109,6 @@ struct _MetaWaylandSurface
|
||||
GSList *pending_placement_ops;
|
||||
} sub;
|
||||
|
||||
gboolean has_set_geometry;
|
||||
|
||||
/* All the pending state that wl_surface.commit will apply. */
|
||||
MetaWaylandPendingState pending;
|
||||
};
|
||||
|
@@ -444,29 +444,6 @@ touch_info_free (MetaWaylandTouchInfo *touch_info)
|
||||
g_free (touch_info);
|
||||
}
|
||||
|
||||
static void
|
||||
touch_handle_cancel_event (MetaWaylandTouch *touch,
|
||||
struct libinput_event *event)
|
||||
{
|
||||
GList *surfaces, *s;
|
||||
|
||||
surfaces = s = touch_get_surfaces (touch, FALSE);
|
||||
|
||||
while (s)
|
||||
{
|
||||
MetaWaylandTouchSurface *touch_surface = s->data;
|
||||
struct wl_resource *resource;
|
||||
struct wl_list *l;
|
||||
|
||||
l = &touch_surface->resource_list;
|
||||
wl_resource_for_each(resource, l)
|
||||
wl_touch_send_cancel (resource);
|
||||
}
|
||||
|
||||
g_hash_table_remove_all (touch->touches);
|
||||
g_list_free (surfaces);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
evdev_filter_func (struct libinput_event *event,
|
||||
gpointer data)
|
||||
@@ -495,7 +472,7 @@ evdev_filter_func (struct libinput_event *event,
|
||||
* which are not so useful when sending a global signal as the protocol
|
||||
* requires.
|
||||
*/
|
||||
touch_handle_cancel_event (touch, event);
|
||||
meta_wayland_touch_cancel (touch);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -543,6 +520,28 @@ meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch,
|
||||
|
||||
cr = wl_resource_create (client, &wl_touch_interface,
|
||||
MIN (META_WL_TOUCH_VERSION, wl_resource_get_version (seat_resource)), id);
|
||||
wl_resource_set_implementation (cr, &touch_interface, touch, unbind_resource);
|
||||
wl_resource_set_implementation (cr, NULL, touch, unbind_resource);
|
||||
wl_list_insert (&touch->resource_list, wl_resource_get_link (cr));
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_touch_cancel (MetaWaylandTouch *touch)
|
||||
{
|
||||
GList *surfaces, *s;
|
||||
|
||||
surfaces = s = touch_get_surfaces (touch, FALSE);
|
||||
|
||||
while (s)
|
||||
{
|
||||
MetaWaylandTouchSurface *touch_surface = s->data;
|
||||
struct wl_resource *resource;
|
||||
struct wl_list *l;
|
||||
|
||||
l = &touch_surface->resource_list;
|
||||
wl_resource_for_each(resource, l)
|
||||
wl_touch_send_cancel (resource);
|
||||
}
|
||||
|
||||
g_hash_table_remove_all (touch->touches);
|
||||
g_list_free (surfaces);
|
||||
}
|
||||
|
@@ -58,5 +58,7 @@ void meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch,
|
||||
struct wl_client *client,
|
||||
struct wl_resource *seat_resource,
|
||||
uint32_t id);
|
||||
void meta_wayland_touch_cancel (MetaWaylandTouch *touch);
|
||||
|
||||
|
||||
#endif /* META_WAYLAND_TOUCH_H */
|
||||
|
@@ -27,9 +27,9 @@ typedef struct _MetaWaylandPointer MetaWaylandPointer;
|
||||
typedef struct _MetaWaylandPointerGrab MetaWaylandPointerGrab;
|
||||
typedef struct _MetaWaylandPointerGrabInterface MetaWaylandPointerGrabInterface;
|
||||
typedef struct _MetaWaylandKeyboard MetaWaylandKeyboard;
|
||||
typedef struct _MetaWaylandTouch MetaWaylandTouch;
|
||||
typedef struct _MetaWaylandDataOffer MetaWaylandDataOffer;
|
||||
typedef struct _MetaWaylandDataSource MetaWaylandDataSource;
|
||||
typedef struct _MetaWaylandDataDevice MetaWaylandDataDevice;
|
||||
typedef struct _MetaWaylandTouch MetaWaylandTouch;
|
||||
|
||||
typedef struct _MetaWaylandBuffer MetaWaylandBuffer;
|
||||
typedef struct _MetaWaylandBufferReference MetaWaylandBufferReference;
|
||||
|
@@ -37,7 +37,6 @@
|
||||
/* Global/master objects (version exported by wl_registry and negotiated through bind) */
|
||||
#define META_WL_COMPOSITOR_VERSION 3
|
||||
#define META_WL_DATA_DEVICE_MANAGER_VERSION 1
|
||||
#define META_XDG_SHELL_VERSION 1
|
||||
#define META_WL_SHELL_VERSION 1
|
||||
#define META_WL_SEAT_VERSION 3
|
||||
#define META_WL_OUTPUT_VERSION 2
|
||||
|
@@ -187,7 +187,9 @@ meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor,
|
||||
{
|
||||
MetaWaylandSurface *surface = window ? window->surface : NULL;
|
||||
|
||||
meta_wayland_seat_set_input_focus (compositor->seat, surface);
|
||||
meta_wayland_keyboard_set_focus (&compositor->seat->keyboard,
|
||||
surface);
|
||||
meta_wayland_data_device_set_keyboard_focus (compositor->seat);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -382,7 +384,6 @@ void
|
||||
meta_wayland_init (void)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = &_meta_wayland_compositor;
|
||||
GSource *wayland_event_source;
|
||||
|
||||
memset (compositor, 0, sizeof (MetaWaylandCompositor));
|
||||
|
||||
@@ -401,7 +402,10 @@ meta_wayland_init (void)
|
||||
compositor, compositor_bind))
|
||||
g_error ("Failed to register wayland compositor object");
|
||||
|
||||
wayland_event_source = wayland_event_source_new (compositor->wayland_display);
|
||||
compositor->wayland_loop =
|
||||
wl_display_get_event_loop (compositor->wayland_display);
|
||||
compositor->wayland_event_source =
|
||||
wayland_event_source_new (compositor->wayland_display);
|
||||
|
||||
/* XXX: Here we are setting the wayland event source to have a
|
||||
* slightly lower priority than the X event source, because we are
|
||||
@@ -412,8 +416,9 @@ meta_wayland_init (void)
|
||||
* At some point we could perhaps try and get the X protocol proxied
|
||||
* over the wayland protocol so that we don't have to worry about
|
||||
* synchronizing the two command streams. */
|
||||
g_source_set_priority (wayland_event_source, GDK_PRIORITY_EVENTS + 1);
|
||||
g_source_attach (wayland_event_source, NULL);
|
||||
g_source_set_priority (compositor->wayland_event_source,
|
||||
GDK_PRIORITY_EVENTS + 1);
|
||||
g_source_attach (compositor->wayland_event_source, NULL);
|
||||
clutter_wayland_set_compositor_display (compositor->wayland_display);
|
||||
|
||||
meta_clutter_init ();
|
||||
|
@@ -146,6 +146,32 @@
|
||||
<arg name="parent" type="object" interface="wl_surface" allow-null="true"/>
|
||||
</request>
|
||||
|
||||
<request name="set_margin">
|
||||
<description summary="set the visible frame boundaries">
|
||||
This tells the compositor what the visible size of the window
|
||||
should be, so it can use it to determine what borders to use for
|
||||
constrainment and alignment.
|
||||
|
||||
CSD often has invisible areas for decoration purposes, like drop
|
||||
shadows. These "shadow" drawings need to be subtracted out of the
|
||||
normal boundaries of the window when computing where to place
|
||||
windows (e.g. to set this window so it's centered on top of another,
|
||||
or to put it to the left or right of the screen.)
|
||||
|
||||
This value should change as little as possible at runtime, to
|
||||
prevent flicker.
|
||||
|
||||
This value is also ignored when the window is maximized or
|
||||
fullscreen, and assumed to be 0.
|
||||
|
||||
If never called, this value is assumed to be 0.
|
||||
</description>
|
||||
<arg name="left_margin" type="int"/>
|
||||
<arg name="right_margin" type="int"/>
|
||||
<arg name="top_margin" type="int"/>
|
||||
<arg name="bottom_margin" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_title">
|
||||
<description summary="set surface title">
|
||||
Set a short title for the surface.
|
||||
@@ -178,18 +204,14 @@
|
||||
a context menu when right-clicking on the decorations, giving the
|
||||
user a menu that they can use to maximize or minimize the window.
|
||||
|
||||
This request asks the compositor to pop up such a window menu at
|
||||
the given position, relative to the parent surface. There are
|
||||
no guarantees as to what the window menu contains.
|
||||
|
||||
Your surface must have focus on the seat passed in to pop up the
|
||||
window menu.
|
||||
The seat passed must have either pointer or keyboard focus to pop
|
||||
up the window menu for a surface.
|
||||
</description>
|
||||
|
||||
<arg name="seat" type="object" interface="wl_seat" summary="the seat to pop the window up on"/>
|
||||
<arg name="serial" type="uint" summary="serial of the event to pop up the window for"/>
|
||||
<arg name="x" type="int" summary="the x position to pop up the window menu at"/>
|
||||
<arg name="y" type="int" summary="the y position to pop up the window menu at"/>
|
||||
<arg name="x" type="uint"/>
|
||||
<arg name="y" type="uint"/>
|
||||
</request>
|
||||
|
||||
<request name="move">
|
||||
@@ -278,11 +300,11 @@
|
||||
</enum>
|
||||
|
||||
<event name="configure">
|
||||
<description summary="suggest a surface change">
|
||||
<description summary="suggest a surface chnage">
|
||||
The configure event asks the client to resize its surface.
|
||||
|
||||
The width and height arguments specify a hint to the window
|
||||
about how its surface should be resized in window geometry
|
||||
about how its surface should be resized in surface local
|
||||
coordinates. The states listed in the event specify how the
|
||||
width/height arguments should be interpreted.
|
||||
|
||||
@@ -313,29 +335,6 @@
|
||||
<arg name="serial" type="uint" summary="a serial to configure for"/>
|
||||
</request>
|
||||
|
||||
<request name="set_window_geometry">
|
||||
<description summary="set the new window geometry">
|
||||
The window geometry of a window is its "visible bounds" from the
|
||||
user's perspective. Client-side decorations often have invisible
|
||||
portions like drop-shadows which should be ignored for the
|
||||
purposes of aligning, placing and constraining windows.
|
||||
|
||||
The default value is the full bounds of the surface, including any
|
||||
subsurfaces. Once the window geometry of the surface is set once,
|
||||
it is not possible to unset it, and it will remain the same until
|
||||
set_window_geometry is called again, even if a new subsurface or
|
||||
buffer is attached.
|
||||
|
||||
If responding to a configure event, the window geometry in here
|
||||
must respect the sizing negotiations specified by the states in
|
||||
the configure event.
|
||||
</description>
|
||||
<arg name="x" type="int"/>
|
||||
<arg name="y" type="int"/>
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_maximized" />
|
||||
<request name="unset_maximized" />
|
||||
|
||||
|
@@ -133,8 +133,7 @@ static void
|
||||
meta_window_wayland_grab_op_began (MetaWindow *window,
|
||||
MetaGrabOp op)
|
||||
{
|
||||
if (meta_grab_op_is_resizing (op))
|
||||
surface_state_changed (window);
|
||||
surface_state_changed (window);
|
||||
|
||||
META_WINDOW_CLASS (meta_window_wayland_parent_class)->grab_op_began (window, op);
|
||||
}
|
||||
@@ -143,8 +142,7 @@ static void
|
||||
meta_window_wayland_grab_op_ended (MetaWindow *window,
|
||||
MetaGrabOp op)
|
||||
{
|
||||
if (meta_grab_op_is_resizing (op))
|
||||
surface_state_changed (window);
|
||||
surface_state_changed (window);
|
||||
|
||||
META_WINDOW_CLASS (meta_window_wayland_parent_class)->grab_op_ended (window, op);
|
||||
}
|
||||
@@ -178,24 +176,9 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
|
||||
* update the real client size to match the buffer size.
|
||||
*/
|
||||
|
||||
if (window->rect.width != unconstrained_rect.width ||
|
||||
window->rect.height != unconstrained_rect.height)
|
||||
{
|
||||
*result |= META_MOVE_RESIZE_RESULT_RESIZED;
|
||||
window->rect.width = unconstrained_rect.width;
|
||||
window->rect.height = unconstrained_rect.height;
|
||||
}
|
||||
|
||||
CoglTexture *texture = window->surface->buffer->texture;
|
||||
int new_buffer_width = cogl_texture_get_width (texture);
|
||||
int new_buffer_height = cogl_texture_get_height (texture);
|
||||
if (window->buffer_rect.width != new_buffer_width ||
|
||||
window->buffer_rect.height != new_buffer_height)
|
||||
{
|
||||
*result |= META_MOVE_RESIZE_RESULT_RESIZED;
|
||||
window->buffer_rect.width = new_buffer_width;
|
||||
window->buffer_rect.height = new_buffer_height;
|
||||
}
|
||||
*result |= META_MOVE_RESIZE_RESULT_RESIZED;
|
||||
window->rect.width = unconstrained_rect.width;
|
||||
window->rect.height = unconstrained_rect.height;
|
||||
|
||||
/* This is a commit of an attach. We should move the window to match the
|
||||
* new position the client wants. */
|
||||
@@ -234,16 +217,6 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
|
||||
window->rect.x = new_x;
|
||||
window->rect.y = new_y;
|
||||
}
|
||||
|
||||
int new_buffer_x = new_x - window->custom_frame_extents.left;
|
||||
int new_buffer_y = new_y - window->custom_frame_extents.top;
|
||||
|
||||
if (new_buffer_x != window->buffer_rect.x || new_buffer_y != window->buffer_rect.y)
|
||||
{
|
||||
*result |= META_MOVE_RESIZE_RESULT_MOVED;
|
||||
window->buffer_rect.x = new_buffer_x;
|
||||
window->buffer_rect.y = new_buffer_y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,20 +322,17 @@ meta_window_wayland_new (MetaDisplay *display,
|
||||
* Complete a resize operation from a wayland client.
|
||||
*/
|
||||
void
|
||||
meta_window_wayland_move_resize (MetaWindow *window,
|
||||
MetaRectangle new_geom,
|
||||
int dx,
|
||||
int dy)
|
||||
meta_window_wayland_move_resize (MetaWindow *window,
|
||||
int width,
|
||||
int height,
|
||||
int dx,
|
||||
int dy)
|
||||
{
|
||||
MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
|
||||
int gravity;
|
||||
MetaRectangle rect;
|
||||
MetaMoveResizeFlags flags;
|
||||
|
||||
/* XXX: Find a better place to store the window geometry offsets. */
|
||||
window->custom_frame_extents.left = new_geom.x;
|
||||
window->custom_frame_extents.top = new_geom.y;
|
||||
|
||||
flags = META_IS_WAYLAND_RESIZE;
|
||||
|
||||
/* x/y are ignored when we're doing interactive resizing */
|
||||
@@ -377,8 +347,7 @@ meta_window_wayland_move_resize (MetaWindow *window,
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.x = window->rect.x;
|
||||
rect.y = window->rect.y;
|
||||
meta_window_get_frame_rect (window, &rect);
|
||||
}
|
||||
|
||||
if (dx != 0 || dy != 0)
|
||||
@@ -389,8 +358,10 @@ meta_window_wayland_move_resize (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
rect.width = new_geom.width;
|
||||
rect.height = new_geom.height;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
window->buffer_rect = rect;
|
||||
|
||||
if (rect.width != window->rect.width || rect.height != window->rect.height)
|
||||
flags |= META_IS_RESIZE_ACTION;
|
||||
|
@@ -45,9 +45,10 @@ typedef struct _MetaWindowWaylandClass MetaWindowWaylandClass;
|
||||
MetaWindow * meta_window_wayland_new (MetaDisplay *display,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
void meta_window_wayland_move_resize (MetaWindow *window,
|
||||
MetaRectangle new_geom,
|
||||
int dx,
|
||||
int dy);
|
||||
void meta_window_wayland_move_resize (MetaWindow *window,
|
||||
int width,
|
||||
int height,
|
||||
int dx,
|
||||
int dy);
|
||||
|
||||
#endif
|
||||
|
@@ -38,6 +38,16 @@
|
||||
#include "wayland/meta-xwayland.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
|
||||
typedef struct _EventFuncData EventFuncData;
|
||||
|
||||
struct _EventFuncData
|
||||
{
|
||||
GFunc func;
|
||||
gpointer data;
|
||||
};
|
||||
|
||||
static GList *event_funcs = NULL;
|
||||
|
||||
static XIEvent *
|
||||
get_input_event (MetaDisplay *display,
|
||||
XEvent *event)
|
||||
@@ -1148,7 +1158,7 @@ process_selection_request (MetaDisplay *display,
|
||||
meta_verbose ("Handled selection request\n");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static void
|
||||
process_selection_clear (MetaDisplay *display,
|
||||
XEvent *event)
|
||||
{
|
||||
@@ -1169,7 +1179,7 @@ process_selection_clear (MetaDisplay *display,
|
||||
|
||||
meta_XFree (str);
|
||||
|
||||
return FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
meta_verbose ("Got selection clear for screen %d on display %s\n",
|
||||
@@ -1177,7 +1187,6 @@ process_selection_clear (MetaDisplay *display,
|
||||
|
||||
meta_display_unmanage_screen (display, display->screen,
|
||||
event->xselectionclear.time);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1773,14 +1782,13 @@ meta_display_handle_xevent (MetaDisplay *display,
|
||||
|
||||
if (event->type == SelectionClear)
|
||||
{
|
||||
if (process_selection_clear (display, event))
|
||||
{
|
||||
/* This means we called meta_display_unmanage_screen, which
|
||||
* means the MetaDisplay is effectively dead. We don't want
|
||||
* to poke into display->current_time below, since that would
|
||||
* crash, so just directly return. */
|
||||
return TRUE;
|
||||
}
|
||||
/* Do this here so we can return without any further
|
||||
* processing. */
|
||||
process_selection_clear (display, event);
|
||||
/* Note that processing that may have resulted in
|
||||
* closing the display... */
|
||||
bypass_gtk = bypass_compositor = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -1803,11 +1811,37 @@ xevent_filter (GdkXEvent *xevent,
|
||||
gpointer data)
|
||||
{
|
||||
MetaDisplay *display = data;
|
||||
EventFuncData *event_data;
|
||||
XIEvent *input_event;
|
||||
GList *l;
|
||||
|
||||
if (meta_display_handle_xevent (display, xevent))
|
||||
return GDK_FILTER_REMOVE;
|
||||
else
|
||||
meta_display_handle_xevent (display, xevent);
|
||||
|
||||
for (l = event_funcs; l; l = l->next)
|
||||
{
|
||||
event_data = l->data;
|
||||
event_data->func (xevent, event_data->data);
|
||||
}
|
||||
|
||||
input_event = get_input_event (display, xevent);
|
||||
|
||||
if (!input_event)
|
||||
return GDK_FILTER_CONTINUE;
|
||||
|
||||
/* Filter all pointer and touch events, those are emulated
|
||||
* above by the filters, and Gdk is bypassed there on purpose.
|
||||
*/
|
||||
if (input_event->evtype == XI_ButtonPress ||
|
||||
input_event->evtype == XI_ButtonRelease ||
|
||||
input_event->evtype == XI_Motion ||
|
||||
input_event->evtype == XI_Enter ||
|
||||
input_event->evtype == XI_Leave ||
|
||||
input_event->evtype == XI_TouchBegin ||
|
||||
input_event->evtype == XI_TouchUpdate ||
|
||||
input_event->evtype == XI_TouchEnd)
|
||||
return GDK_FILTER_REMOVE;
|
||||
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1821,3 +1855,37 @@ meta_display_free_events_x11 (MetaDisplay *display)
|
||||
{
|
||||
gdk_window_remove_filter (NULL, xevent_filter, display);
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_events_x11_add_func (GFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
EventFuncData *data;
|
||||
|
||||
data = g_slice_new0 (EventFuncData);
|
||||
data->func = func;
|
||||
data->data = user_data;
|
||||
event_funcs = g_list_prepend (event_funcs, data);
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_events_x11_remove_func (GFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
EventFuncData *data;
|
||||
GList *l;
|
||||
|
||||
data = g_slice_new0 (EventFuncData);
|
||||
|
||||
for (l = event_funcs; l; l = l->next)
|
||||
{
|
||||
data = l->data;
|
||||
|
||||
if (data->func != func || data->data != user_data)
|
||||
continue;
|
||||
|
||||
event_funcs = g_list_delete_link (event_funcs, l);
|
||||
g_slice_free (EventFuncData, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -28,4 +28,9 @@
|
||||
void meta_display_init_events_x11 (MetaDisplay *display);
|
||||
void meta_display_free_events_x11 (MetaDisplay *display);
|
||||
|
||||
void meta_display_events_x11_add_func (GFunc func,
|
||||
gpointer user_data);
|
||||
void meta_display_events_x11_remove_func (GFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
#endif
|
||||
|
@@ -28,6 +28,22 @@
|
||||
|
||||
/* The icon-reading code is also in libwnck, please sync bugfixes */
|
||||
|
||||
static void
|
||||
get_fallback_icons (MetaScreen *screen,
|
||||
GdkPixbuf **iconp,
|
||||
int ideal_width,
|
||||
int ideal_height,
|
||||
GdkPixbuf **mini_iconp,
|
||||
int ideal_mini_width,
|
||||
int ideal_mini_height)
|
||||
{
|
||||
/* we don't scale, should be fixed if we ever un-hardcode the icon
|
||||
* size
|
||||
*/
|
||||
*iconp = meta_ui_get_default_window_icon (screen->ui);
|
||||
*mini_iconp = meta_ui_get_default_mini_icon (screen->ui);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
find_largest_sizes (gulong *data,
|
||||
gulong nitems,
|
||||
@@ -526,11 +542,50 @@ meta_icon_cache_init (MetaIconCache *icon_cache)
|
||||
icon_cache->origin = USING_NO_ICON;
|
||||
icon_cache->prev_pixmap = None;
|
||||
icon_cache->prev_mask = None;
|
||||
#if 0
|
||||
icon_cache->icon = NULL;
|
||||
icon_cache->mini_icon = NULL;
|
||||
icon_cache->ideal_width = -1; /* won't be a legit width */
|
||||
icon_cache->ideal_height = -1;
|
||||
icon_cache->ideal_mini_width = -1;
|
||||
icon_cache->ideal_mini_height = -1;
|
||||
#endif
|
||||
icon_cache->want_fallback = TRUE;
|
||||
icon_cache->wm_hints_dirty = TRUE;
|
||||
icon_cache->kwm_win_icon_dirty = TRUE;
|
||||
icon_cache->net_wm_icon_dirty = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_icon_cache (MetaIconCache *icon_cache,
|
||||
gboolean dirty_all)
|
||||
{
|
||||
#if 0
|
||||
if (icon_cache->icon)
|
||||
g_object_unref (G_OBJECT (icon_cache->icon));
|
||||
icon_cache->icon = NULL;
|
||||
|
||||
if (icon_cache->mini_icon)
|
||||
g_object_unref (G_OBJECT (icon_cache->mini_icon));
|
||||
icon_cache->mini_icon = NULL;
|
||||
#endif
|
||||
|
||||
icon_cache->origin = USING_NO_ICON;
|
||||
|
||||
if (dirty_all)
|
||||
{
|
||||
icon_cache->wm_hints_dirty = TRUE;
|
||||
icon_cache->kwm_win_icon_dirty = TRUE;
|
||||
icon_cache->net_wm_icon_dirty = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_icon_cache_free (MetaIconCache *icon_cache)
|
||||
{
|
||||
clear_icon_cache (icon_cache, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_icon_cache_property_changed (MetaIconCache *icon_cache,
|
||||
MetaDisplay *display,
|
||||
@@ -556,12 +611,41 @@ meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache)
|
||||
else if (icon_cache->origin <= USING_NET_WM_ICON &&
|
||||
icon_cache->net_wm_icon_dirty)
|
||||
return TRUE;
|
||||
else if (icon_cache->origin < USING_FALLBACK_ICON)
|
||||
else if (icon_cache->origin < USING_FALLBACK_ICON &&
|
||||
icon_cache->want_fallback)
|
||||
return TRUE;
|
||||
else if (icon_cache->origin == USING_NO_ICON)
|
||||
return TRUE;
|
||||
else if (icon_cache->origin == USING_FALLBACK_ICON &&
|
||||
!icon_cache->want_fallback)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
replace_cache (MetaIconCache *icon_cache,
|
||||
IconOrigin origin,
|
||||
GdkPixbuf *new_icon,
|
||||
GdkPixbuf *new_mini_icon)
|
||||
{
|
||||
clear_icon_cache (icon_cache, FALSE);
|
||||
|
||||
icon_cache->origin = origin;
|
||||
|
||||
#if 0
|
||||
if (new_icon)
|
||||
g_object_ref (G_OBJECT (new_icon));
|
||||
|
||||
icon_cache->icon = new_icon;
|
||||
|
||||
if (new_mini_icon)
|
||||
g_object_ref (G_OBJECT (new_mini_icon));
|
||||
|
||||
icon_cache->mini_icon = new_mini_icon;
|
||||
#endif
|
||||
}
|
||||
|
||||
static GdkPixbuf*
|
||||
scaled_from_pixdata (guchar *pixdata,
|
||||
int w,
|
||||
@@ -631,6 +715,13 @@ meta_read_icons (MetaScreen *screen,
|
||||
int ideal_mini_width,
|
||||
int ideal_mini_height)
|
||||
{
|
||||
guchar *pixdata;
|
||||
int w, h;
|
||||
guchar *mini_pixdata;
|
||||
int mini_w, mini_h;
|
||||
Pixmap pixmap;
|
||||
Pixmap mask;
|
||||
|
||||
/* Return value is whether the icon changed */
|
||||
|
||||
g_return_val_if_fail (icon_cache != NULL, FALSE);
|
||||
@@ -638,9 +729,24 @@ meta_read_icons (MetaScreen *screen,
|
||||
*iconp = NULL;
|
||||
*mini_iconp = NULL;
|
||||
|
||||
#if 0
|
||||
if (ideal_width != icon_cache->ideal_width ||
|
||||
ideal_height != icon_cache->ideal_height ||
|
||||
ideal_mini_width != icon_cache->ideal_mini_width ||
|
||||
ideal_mini_height != icon_cache->ideal_mini_height)
|
||||
clear_icon_cache (icon_cache, TRUE);
|
||||
|
||||
icon_cache->ideal_width = ideal_width;
|
||||
icon_cache->ideal_height = ideal_height;
|
||||
icon_cache->ideal_mini_width = ideal_mini_width;
|
||||
icon_cache->ideal_mini_height = ideal_mini_height;
|
||||
#endif
|
||||
|
||||
if (!meta_icon_cache_get_icon_invalidated (icon_cache))
|
||||
return FALSE; /* we have no new info to use */
|
||||
|
||||
pixdata = NULL;
|
||||
|
||||
/* Our algorithm here assumes that we can't have for example origin
|
||||
* < USING_NET_WM_ICON and icon_cache->net_wm_icon_dirty == FALSE
|
||||
* unless we have tried to read NET_WM_ICON.
|
||||
@@ -652,12 +758,8 @@ meta_read_icons (MetaScreen *screen,
|
||||
|
||||
if (icon_cache->origin <= USING_NET_WM_ICON &&
|
||||
icon_cache->net_wm_icon_dirty)
|
||||
{
|
||||
guchar *pixdata;
|
||||
int w, h;
|
||||
guchar *mini_pixdata;
|
||||
int mini_w, mini_h;
|
||||
|
||||
{
|
||||
icon_cache->net_wm_icon_dirty = FALSE;
|
||||
|
||||
if (read_rgb_icon (screen->display, xwindow,
|
||||
@@ -674,7 +776,9 @@ meta_read_icons (MetaScreen *screen,
|
||||
|
||||
if (*iconp && *mini_iconp)
|
||||
{
|
||||
icon_cache->origin = USING_NET_WM_ICON;
|
||||
replace_cache (icon_cache, USING_NET_WM_ICON,
|
||||
*iconp, *mini_iconp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
@@ -690,9 +794,6 @@ meta_read_icons (MetaScreen *screen,
|
||||
if (icon_cache->origin <= USING_WM_HINTS &&
|
||||
icon_cache->wm_hints_dirty)
|
||||
{
|
||||
Pixmap pixmap;
|
||||
Pixmap mask;
|
||||
|
||||
icon_cache->wm_hints_dirty = FALSE;
|
||||
|
||||
pixmap = wm_hints_pixmap;
|
||||
@@ -713,7 +814,10 @@ meta_read_icons (MetaScreen *screen,
|
||||
{
|
||||
icon_cache->prev_pixmap = pixmap;
|
||||
icon_cache->prev_mask = mask;
|
||||
icon_cache->origin = USING_WM_HINTS;
|
||||
|
||||
replace_cache (icon_cache, USING_WM_HINTS,
|
||||
*iconp, *mini_iconp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -722,9 +826,6 @@ meta_read_icons (MetaScreen *screen,
|
||||
if (icon_cache->origin <= USING_KWM_WIN_ICON &&
|
||||
icon_cache->kwm_win_icon_dirty)
|
||||
{
|
||||
Pixmap pixmap;
|
||||
Pixmap mask;
|
||||
|
||||
icon_cache->kwm_win_icon_dirty = FALSE;
|
||||
|
||||
get_kwm_win_icon (screen->display, xwindow, &pixmap, &mask);
|
||||
@@ -739,17 +840,38 @@ meta_read_icons (MetaScreen *screen,
|
||||
{
|
||||
icon_cache->prev_pixmap = pixmap;
|
||||
icon_cache->prev_mask = mask;
|
||||
icon_cache->origin = USING_KWM_WIN_ICON;
|
||||
|
||||
replace_cache (icon_cache, USING_KWM_WIN_ICON,
|
||||
*iconp, *mini_iconp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (icon_cache->origin < USING_FALLBACK_ICON)
|
||||
if (icon_cache->want_fallback &&
|
||||
icon_cache->origin < USING_FALLBACK_ICON)
|
||||
{
|
||||
icon_cache->origin = USING_FALLBACK_ICON;
|
||||
*iconp = NULL;
|
||||
*mini_iconp = NULL;
|
||||
get_fallback_icons (screen,
|
||||
iconp,
|
||||
ideal_width,
|
||||
ideal_height,
|
||||
mini_iconp,
|
||||
ideal_mini_width,
|
||||
ideal_mini_height);
|
||||
|
||||
replace_cache (icon_cache, USING_FALLBACK_ICON,
|
||||
*iconp, *mini_iconp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!icon_cache->want_fallback &&
|
||||
icon_cache->origin == USING_FALLBACK_ICON)
|
||||
{
|
||||
/* Get rid of current icon */
|
||||
clear_icon_cache (icon_cache, FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@@ -44,6 +44,7 @@ struct _MetaIconCache
|
||||
int origin;
|
||||
Pixmap prev_pixmap;
|
||||
Pixmap prev_mask;
|
||||
guint want_fallback : 1;
|
||||
/* TRUE if these props have changed */
|
||||
guint wm_hints_dirty : 1;
|
||||
guint kwm_win_icon_dirty : 1;
|
||||
@@ -51,6 +52,7 @@ struct _MetaIconCache
|
||||
};
|
||||
|
||||
void meta_icon_cache_init (MetaIconCache *icon_cache);
|
||||
void meta_icon_cache_free (MetaIconCache *icon_cache);
|
||||
void meta_icon_cache_property_changed (MetaIconCache *icon_cache,
|
||||
MetaDisplay *display,
|
||||
Atom atom);
|
||||
|
@@ -59,19 +59,13 @@ typedef void (* ReloadValueFunc) (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial);
|
||||
|
||||
typedef enum {
|
||||
NONE = 0,
|
||||
LOAD_INIT = (1 << 0),
|
||||
INCLUDE_OR = (1 << 1),
|
||||
INIT_ONLY = (1 << 2),
|
||||
} MetaPropHookFlags;
|
||||
|
||||
struct _MetaWindowPropHooks
|
||||
{
|
||||
Atom property;
|
||||
MetaPropValueType type;
|
||||
ReloadValueFunc reload_func;
|
||||
MetaPropHookFlags flags;
|
||||
gboolean load_initially;
|
||||
gboolean include_override_redirect;
|
||||
};
|
||||
|
||||
static void init_prop_value (MetaWindow *window,
|
||||
@@ -98,9 +92,6 @@ meta_window_reload_property_from_xwindow (MetaWindow *window,
|
||||
if (!hooks)
|
||||
return;
|
||||
|
||||
if ((hooks->flags & INIT_ONLY) && !initial)
|
||||
return;
|
||||
|
||||
init_prop_value (window, hooks, &value);
|
||||
|
||||
meta_prop_get_values (window->display, xwindow,
|
||||
@@ -136,7 +127,7 @@ meta_window_load_initial_properties (MetaWindow *window)
|
||||
for (i = 0; i < window->display->n_prop_hooks; i++)
|
||||
{
|
||||
MetaWindowPropHooks *hooks = &window->display->prop_hooks_table[i];
|
||||
if (hooks->flags & LOAD_INIT)
|
||||
if (hooks->load_initially)
|
||||
{
|
||||
init_prop_value (window, hooks, &values[j]);
|
||||
++j;
|
||||
@@ -151,7 +142,7 @@ meta_window_load_initial_properties (MetaWindow *window)
|
||||
for (i = 0; i < window->display->n_prop_hooks; i++)
|
||||
{
|
||||
MetaWindowPropHooks *hooks = &window->display->prop_hooks_table[i];
|
||||
if (hooks->flags & LOAD_INIT)
|
||||
if (hooks->load_initially)
|
||||
{
|
||||
/* If we didn't actually manage to load anything then we don't need
|
||||
* to call the reload function; this is different from a notification
|
||||
@@ -175,7 +166,7 @@ init_prop_value (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
if (!hooks || hooks->type == META_PROP_VALUE_INVALID ||
|
||||
(window->override_redirect && !(hooks->flags & INCLUDE_OR)))
|
||||
(window->override_redirect && !hooks->include_override_redirect))
|
||||
{
|
||||
value->type = META_PROP_VALUE_INVALID;
|
||||
value->atom = None;
|
||||
@@ -193,7 +184,8 @@ reload_prop_value (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (!(window->override_redirect && !(hooks->flags & INCLUDE_OR)))
|
||||
if (hooks && hooks->reload_func != NULL &&
|
||||
!(window->override_redirect && !hooks->include_override_redirect))
|
||||
(* hooks->reload_func) (window, value, initial);
|
||||
}
|
||||
|
||||
@@ -239,52 +231,14 @@ reload_net_wm_window_type (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = window_x11->priv;
|
||||
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < value->v.atom_list.n_atoms; i++)
|
||||
{
|
||||
Atom atom = value->v.atom_list.atoms[i];
|
||||
|
||||
/* We break as soon as we find one we recognize,
|
||||
* supposed to prefer those near the front of the list
|
||||
*/
|
||||
if (atom == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP ||
|
||||
atom == window->display->atom__NET_WM_WINDOW_TYPE_DOCK ||
|
||||
atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR ||
|
||||
atom == window->display->atom__NET_WM_WINDOW_TYPE_MENU ||
|
||||
atom == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY ||
|
||||
atom == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH ||
|
||||
atom == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG ||
|
||||
atom == window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU ||
|
||||
atom == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU ||
|
||||
atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP ||
|
||||
atom == window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION ||
|
||||
atom == window->display->atom__NET_WM_WINDOW_TYPE_COMBO ||
|
||||
atom == window->display->atom__NET_WM_WINDOW_TYPE_DND ||
|
||||
atom == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL)
|
||||
{
|
||||
priv->type_atom = atom;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
meta_window_x11_recalc_window_type (window);
|
||||
meta_window_x11_update_net_wm_type (window);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_icon (MetaWindow *window,
|
||||
Atom atom)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = window_x11->priv;
|
||||
|
||||
meta_icon_cache_property_changed (&priv->icon_cache,
|
||||
meta_icon_cache_property_changed (&window->icon_cache,
|
||||
window->display,
|
||||
atom);
|
||||
meta_window_queue(window, META_QUEUE_UPDATE_ICON);
|
||||
@@ -380,9 +334,7 @@ reload_wm_window_role (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
g_clear_pointer (&window->role, g_free);
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
window->role = g_strdup (value->v.str);
|
||||
meta_window_x11_update_role (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -610,72 +562,12 @@ reload_wm_name (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_set_opaque_region (MetaWindow *window,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
if (cairo_region_equal (window->opaque_region, region))
|
||||
return;
|
||||
|
||||
g_clear_pointer (&window->opaque_region, cairo_region_destroy);
|
||||
|
||||
if (region != NULL)
|
||||
window->opaque_region = cairo_region_reference (region);
|
||||
|
||||
meta_compositor_window_shape_changed (window->display->compositor, window);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_opaque_region (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
cairo_region_t *opaque_region = NULL;
|
||||
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
gulong *region = value->v.cardinal_list.cardinals;
|
||||
int nitems = value->v.cardinal_list.n_cardinals;
|
||||
|
||||
cairo_rectangle_int_t *rects;
|
||||
int i, rect_index, nrects;
|
||||
|
||||
if (nitems % 4 != 0)
|
||||
{
|
||||
meta_verbose ("_NET_WM_OPAQUE_REGION does not have a list of 4-tuples.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* empty region */
|
||||
if (nitems == 0)
|
||||
goto out;
|
||||
|
||||
nrects = nitems / 4;
|
||||
|
||||
rects = g_new (cairo_rectangle_int_t, nrects);
|
||||
|
||||
rect_index = 0;
|
||||
i = 0;
|
||||
while (i < nitems)
|
||||
{
|
||||
cairo_rectangle_int_t *rect = &rects[rect_index];
|
||||
|
||||
rect->x = region[i++];
|
||||
rect->y = region[i++];
|
||||
rect->width = region[i++];
|
||||
rect->height = region[i++];
|
||||
|
||||
rect_index++;
|
||||
}
|
||||
|
||||
opaque_region = cairo_region_create_rectangles (rects, nrects);
|
||||
|
||||
g_free (rects);
|
||||
}
|
||||
|
||||
out:
|
||||
meta_window_set_opaque_region (window, opaque_region);
|
||||
cairo_region_destroy (opaque_region);
|
||||
meta_window_x11_update_opaque_region (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1498,8 +1390,6 @@ reload_wm_hints (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = window_x11->priv;
|
||||
Window old_group_leader;
|
||||
gboolean urgent;
|
||||
|
||||
@@ -1509,8 +1399,8 @@ reload_wm_hints (MetaWindow *window,
|
||||
window->input = TRUE;
|
||||
window->initially_iconic = FALSE;
|
||||
window->xgroup_leader = None;
|
||||
priv->wm_hints_pixmap = None;
|
||||
priv->wm_hints_mask = None;
|
||||
window->wm_hints_pixmap = None;
|
||||
window->wm_hints_mask = None;
|
||||
urgent = FALSE;
|
||||
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
@@ -1527,10 +1417,10 @@ reload_wm_hints (MetaWindow *window,
|
||||
window->xgroup_leader = hints->window_group;
|
||||
|
||||
if (hints->flags & IconPixmapHint)
|
||||
priv->wm_hints_pixmap = hints->icon_pixmap;
|
||||
window->wm_hints_pixmap = hints->icon_pixmap;
|
||||
|
||||
if (hints->flags & IconMaskHint)
|
||||
priv->wm_hints_mask = hints->icon_mask;
|
||||
window->wm_hints_mask = hints->icon_mask;
|
||||
|
||||
if (hints->flags & XUrgencyHint)
|
||||
urgent = TRUE;
|
||||
@@ -1538,8 +1428,8 @@ reload_wm_hints (MetaWindow *window,
|
||||
meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%lx pixmap: 0x%lx mask: 0x%lx\n",
|
||||
window->input, window->initially_iconic,
|
||||
window->xgroup_leader,
|
||||
priv->wm_hints_pixmap,
|
||||
priv->wm_hints_mask);
|
||||
window->wm_hints_pixmap,
|
||||
window->wm_hints_mask);
|
||||
}
|
||||
|
||||
if (window->xgroup_leader != old_group_leader)
|
||||
@@ -1552,7 +1442,7 @@ reload_wm_hints (MetaWindow *window,
|
||||
|
||||
meta_window_set_urgent (window, urgent);
|
||||
|
||||
meta_icon_cache_property_changed (&priv->icon_cache,
|
||||
meta_icon_cache_property_changed (&window->icon_cache,
|
||||
window->display,
|
||||
XA_WM_HINTS);
|
||||
|
||||
@@ -1758,7 +1648,10 @@ RELOAD_STRING (gtk_menubar_object_path, "gtk-menubar-object-path")
|
||||
void
|
||||
meta_display_init_window_prop_hooks (MetaDisplay *display)
|
||||
{
|
||||
/* The ordering here is significant for the properties we load
|
||||
/* INIT: load initially
|
||||
* O-R: fetch for override-redirect windows
|
||||
*
|
||||
* The ordering here is significant for the properties we load
|
||||
* initially: they are roughly ordered in the order we want them to
|
||||
* be gotten. We want to get window name and class first so we can
|
||||
* use them in error messages and such. However, name is modified
|
||||
@@ -1771,45 +1664,46 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
|
||||
* - NET_WM_WINDOW_TYPE: can be used to do appropriate handling
|
||||
* for different types of override-redirect windows.
|
||||
*/
|
||||
MetaWindowPropHooks hooks[] = {
|
||||
{ display->atom_WM_CLIENT_MACHINE, META_PROP_VALUE_STRING, reload_wm_client_machine, LOAD_INIT | INCLUDE_OR },
|
||||
{ display->atom__NET_WM_NAME, META_PROP_VALUE_UTF8, reload_net_wm_name, LOAD_INIT | INCLUDE_OR },
|
||||
{ XA_WM_CLASS, META_PROP_VALUE_CLASS_HINT, reload_wm_class, LOAD_INIT | INCLUDE_OR },
|
||||
{ display->atom__NET_WM_PID, META_PROP_VALUE_CARDINAL, reload_net_wm_pid, LOAD_INIT | INCLUDE_OR },
|
||||
{ XA_WM_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_name, LOAD_INIT | INCLUDE_OR },
|
||||
{ display->atom__MUTTER_HINTS, META_PROP_VALUE_TEXT_PROPERTY, reload_mutter_hints, LOAD_INIT | INCLUDE_OR },
|
||||
{ display->atom__NET_WM_OPAQUE_REGION, META_PROP_VALUE_CARDINAL_LIST, reload_opaque_region, LOAD_INIT | INCLUDE_OR },
|
||||
{ display->atom__NET_WM_DESKTOP, META_PROP_VALUE_CARDINAL, reload_net_wm_desktop, LOAD_INIT | INIT_ONLY },
|
||||
{ display->atom__NET_STARTUP_ID, META_PROP_VALUE_UTF8, reload_net_startup_id, LOAD_INIT },
|
||||
{ display->atom__NET_WM_SYNC_REQUEST_COUNTER, META_PROP_VALUE_SYNC_COUNTER_LIST, reload_update_counter, LOAD_INIT | INCLUDE_OR },
|
||||
{ XA_WM_NORMAL_HINTS, META_PROP_VALUE_SIZE_HINTS, reload_normal_hints, LOAD_INIT },
|
||||
{ display->atom_WM_PROTOCOLS, META_PROP_VALUE_ATOM_LIST, reload_wm_protocols, LOAD_INIT },
|
||||
{ XA_WM_HINTS, META_PROP_VALUE_WM_HINTS, reload_wm_hints, LOAD_INIT },
|
||||
{ display->atom__NET_WM_USER_TIME, META_PROP_VALUE_CARDINAL, reload_net_wm_user_time, LOAD_INIT },
|
||||
{ display->atom__NET_WM_STATE, META_PROP_VALUE_ATOM_LIST, reload_net_wm_state, LOAD_INIT | INIT_ONLY },
|
||||
{ display->atom__MOTIF_WM_HINTS, META_PROP_VALUE_MOTIF_HINTS, reload_mwm_hints, LOAD_INIT },
|
||||
{ XA_WM_TRANSIENT_FOR, META_PROP_VALUE_WINDOW, reload_transient_for, LOAD_INIT },
|
||||
{ display->atom__GTK_THEME_VARIANT, META_PROP_VALUE_UTF8, reload_gtk_theme_variant, LOAD_INIT },
|
||||
{ display->atom__GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED, META_PROP_VALUE_CARDINAL, reload_gtk_hide_titlebar_when_maximized, LOAD_INIT },
|
||||
{ display->atom__GTK_APPLICATION_ID, META_PROP_VALUE_UTF8, reload_gtk_application_id, LOAD_INIT },
|
||||
{ display->atom__GTK_UNIQUE_BUS_NAME, META_PROP_VALUE_UTF8, reload_gtk_unique_bus_name, LOAD_INIT },
|
||||
{ display->atom__GTK_APPLICATION_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_application_object_path, LOAD_INIT },
|
||||
{ display->atom__GTK_WINDOW_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_window_object_path, LOAD_INIT },
|
||||
{ display->atom__GTK_APP_MENU_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_app_menu_object_path, LOAD_INIT },
|
||||
{ display->atom__GTK_MENUBAR_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_menubar_object_path, LOAD_INIT },
|
||||
{ display->atom__GTK_FRAME_EXTENTS, META_PROP_VALUE_CARDINAL_LIST,reload_gtk_frame_extents, LOAD_INIT },
|
||||
{ display->atom__NET_WM_USER_TIME_WINDOW, META_PROP_VALUE_WINDOW, reload_net_wm_user_time_window, LOAD_INIT },
|
||||
{ display->atom__NET_WM_ICON, META_PROP_VALUE_INVALID, reload_net_wm_icon, NONE },
|
||||
{ display->atom__KWM_WIN_ICON, META_PROP_VALUE_INVALID, reload_kwm_win_icon, NONE },
|
||||
{ display->atom__NET_WM_ICON_GEOMETRY, META_PROP_VALUE_CARDINAL_LIST, reload_icon_geometry, LOAD_INIT },
|
||||
{ display->atom_WM_CLIENT_LEADER, META_PROP_VALUE_INVALID, complain_about_broken_client, NONE },
|
||||
{ display->atom_SM_CLIENT_ID, META_PROP_VALUE_INVALID, complain_about_broken_client, NONE },
|
||||
{ display->atom_WM_WINDOW_ROLE, META_PROP_VALUE_STRING, reload_wm_window_role, LOAD_INIT },
|
||||
{ display->atom__NET_WM_WINDOW_TYPE, META_PROP_VALUE_ATOM_LIST, reload_net_wm_window_type, LOAD_INIT | INCLUDE_OR },
|
||||
{ display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, NONE },
|
||||
{ display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, NONE },
|
||||
{ display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, NONE },
|
||||
{ display->atom__NET_WM_WINDOW_OPACITY, META_PROP_VALUE_CARDINAL, reload_window_opacity, LOAD_INIT | INCLUDE_OR },
|
||||
MetaWindowPropHooks hooks[] = { /* INIT O-R */
|
||||
{ display->atom_WM_CLIENT_MACHINE, META_PROP_VALUE_STRING, reload_wm_client_machine, TRUE, TRUE },
|
||||
{ display->atom__NET_WM_NAME, META_PROP_VALUE_UTF8, reload_net_wm_name, TRUE, TRUE },
|
||||
{ XA_WM_CLASS, META_PROP_VALUE_CLASS_HINT, reload_wm_class, TRUE, TRUE },
|
||||
{ display->atom__NET_WM_PID, META_PROP_VALUE_CARDINAL, reload_net_wm_pid, TRUE, TRUE },
|
||||
{ XA_WM_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_name, TRUE, TRUE },
|
||||
{ display->atom__MUTTER_HINTS, META_PROP_VALUE_TEXT_PROPERTY, reload_mutter_hints, TRUE, TRUE },
|
||||
{ display->atom__NET_WM_OPAQUE_REGION, META_PROP_VALUE_CARDINAL_LIST, reload_opaque_region, TRUE, TRUE },
|
||||
{ display->atom__NET_WM_DESKTOP, META_PROP_VALUE_CARDINAL, reload_net_wm_desktop, TRUE, FALSE },
|
||||
{ display->atom__NET_STARTUP_ID, META_PROP_VALUE_UTF8, reload_net_startup_id, TRUE, FALSE },
|
||||
{ display->atom__NET_WM_SYNC_REQUEST_COUNTER, META_PROP_VALUE_SYNC_COUNTER_LIST, reload_update_counter, TRUE, TRUE },
|
||||
{ XA_WM_NORMAL_HINTS, META_PROP_VALUE_SIZE_HINTS, reload_normal_hints, TRUE, FALSE },
|
||||
{ display->atom_WM_PROTOCOLS, META_PROP_VALUE_ATOM_LIST, reload_wm_protocols, TRUE, FALSE },
|
||||
{ XA_WM_HINTS, META_PROP_VALUE_WM_HINTS, reload_wm_hints, TRUE, FALSE },
|
||||
{ display->atom__NET_WM_USER_TIME, META_PROP_VALUE_CARDINAL, reload_net_wm_user_time, TRUE, FALSE },
|
||||
{ display->atom__NET_WM_STATE, META_PROP_VALUE_ATOM_LIST, reload_net_wm_state, TRUE, FALSE },
|
||||
{ display->atom__MOTIF_WM_HINTS, META_PROP_VALUE_MOTIF_HINTS, reload_mwm_hints, TRUE, FALSE },
|
||||
{ XA_WM_TRANSIENT_FOR, META_PROP_VALUE_WINDOW, reload_transient_for, TRUE, FALSE },
|
||||
{ display->atom__GTK_THEME_VARIANT, META_PROP_VALUE_UTF8, reload_gtk_theme_variant, TRUE, FALSE },
|
||||
{ display->atom__GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED, META_PROP_VALUE_CARDINAL, reload_gtk_hide_titlebar_when_maximized, TRUE, FALSE },
|
||||
{ display->atom__GTK_APPLICATION_ID, META_PROP_VALUE_UTF8, reload_gtk_application_id, TRUE, FALSE },
|
||||
{ display->atom__GTK_UNIQUE_BUS_NAME, META_PROP_VALUE_UTF8, reload_gtk_unique_bus_name, TRUE, FALSE },
|
||||
{ display->atom__GTK_APPLICATION_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_application_object_path, TRUE, FALSE },
|
||||
{ display->atom__GTK_WINDOW_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_window_object_path, TRUE, FALSE },
|
||||
{ display->atom__GTK_APP_MENU_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_app_menu_object_path, TRUE, FALSE },
|
||||
{ display->atom__GTK_MENUBAR_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_menubar_object_path, TRUE, FALSE },
|
||||
{ display->atom__GTK_FRAME_EXTENTS, META_PROP_VALUE_CARDINAL_LIST,reload_gtk_frame_extents, TRUE, FALSE },
|
||||
{ display->atom__NET_WM_USER_TIME_WINDOW, META_PROP_VALUE_WINDOW, reload_net_wm_user_time_window, TRUE, FALSE },
|
||||
{ display->atom_WM_STATE, META_PROP_VALUE_INVALID, NULL, FALSE, FALSE },
|
||||
{ display->atom__NET_WM_ICON, META_PROP_VALUE_INVALID, reload_net_wm_icon, FALSE, FALSE },
|
||||
{ display->atom__KWM_WIN_ICON, META_PROP_VALUE_INVALID, reload_kwm_win_icon, FALSE, FALSE },
|
||||
{ display->atom__NET_WM_ICON_GEOMETRY, META_PROP_VALUE_CARDINAL_LIST, reload_icon_geometry, FALSE, FALSE },
|
||||
{ display->atom_WM_CLIENT_LEADER, META_PROP_VALUE_INVALID, complain_about_broken_client, FALSE, FALSE },
|
||||
{ display->atom_SM_CLIENT_ID, META_PROP_VALUE_INVALID, complain_about_broken_client, FALSE, FALSE },
|
||||
{ display->atom_WM_WINDOW_ROLE, META_PROP_VALUE_INVALID, reload_wm_window_role, TRUE, FALSE },
|
||||
{ display->atom__NET_WM_WINDOW_TYPE, META_PROP_VALUE_INVALID, reload_net_wm_window_type, TRUE, TRUE },
|
||||
{ display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE },
|
||||
{ display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE },
|
||||
{ display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, FALSE, FALSE },
|
||||
{ display->atom__NET_WM_WINDOW_OPACITY, META_PROP_VALUE_CARDINAL, reload_window_opacity, TRUE, TRUE },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
@@ -1824,7 +1718,7 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
|
||||
while (cursor->property)
|
||||
{
|
||||
/* Doing initial loading doesn't make sense if we just want notification */
|
||||
g_assert (!((cursor->flags & LOAD_INIT) && cursor->type == META_PROP_VALUE_INVALID));
|
||||
g_assert (!(hooks->load_initially && hooks->type == META_PROP_VALUE_INVALID));
|
||||
|
||||
/* Atoms are safe to use with GINT_TO_POINTER because it's safe with
|
||||
* anything 32 bits or less, and atoms are 32 bits with the top three
|
||||
|
@@ -24,7 +24,6 @@
|
||||
#define META_WINDOW_X11_PRIVATE_H
|
||||
|
||||
#include "window-private.h"
|
||||
#include "x11/iconcache.h"
|
||||
#include "ui/resizepopup.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -61,10 +60,6 @@ struct _MetaWindowX11Private
|
||||
/* These are in server coordinates. If we have a frame, it's
|
||||
* relative to the frame. */
|
||||
MetaRectangle client_rect;
|
||||
|
||||
MetaIconCache icon_cache;
|
||||
Pixmap wm_hints_pixmap;
|
||||
Pixmap wm_hints_mask;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -503,10 +503,6 @@ static void
|
||||
meta_window_x11_manage (MetaWindow *window)
|
||||
{
|
||||
MetaDisplay *display = window->display;
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
|
||||
meta_icon_cache_init (&priv->icon_cache);
|
||||
|
||||
meta_display_register_x_window (display, &window->xwindow, window);
|
||||
meta_window_x11_update_shape_region (window);
|
||||
@@ -522,6 +518,8 @@ meta_window_x11_manage (MetaWindow *window)
|
||||
if (!window->override_redirect)
|
||||
update_sm_hints (window); /* must come after transient_for */
|
||||
|
||||
meta_window_x11_update_net_wm_type (window);
|
||||
|
||||
if (window->decorated)
|
||||
meta_window_ensure_frame (window);
|
||||
|
||||
@@ -548,6 +546,9 @@ meta_window_x11_manage (MetaWindow *window)
|
||||
|
||||
if (window->override_redirect)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
|
||||
priv->client_rect = window->rect;
|
||||
window->buffer_rect = window->rect;
|
||||
}
|
||||
@@ -1449,25 +1450,6 @@ meta_window_x11_get_default_skip_hints (MetaWindow *window,
|
||||
*skip_pager_out = priv->wm_state_skip_pager;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_window_x11_update_icon (MetaWindow *window,
|
||||
GdkPixbuf **icon,
|
||||
GdkPixbuf **mini_icon)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
|
||||
return meta_read_icons (window->screen,
|
||||
window->xwindow,
|
||||
&priv->icon_cache,
|
||||
priv->wm_hints_pixmap,
|
||||
priv->wm_hints_mask,
|
||||
icon,
|
||||
META_ICON_WIDTH, META_ICON_HEIGHT,
|
||||
mini_icon,
|
||||
META_MINI_ICON_WIDTH, META_MINI_ICON_HEIGHT);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_x11_class_init (MetaWindowX11Class *klass)
|
||||
{
|
||||
@@ -1485,7 +1467,6 @@ meta_window_x11_class_init (MetaWindowX11Class *klass)
|
||||
window_class->move_resize_internal = meta_window_x11_move_resize_internal;
|
||||
window_class->update_struts = meta_window_x11_update_struts;
|
||||
window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints;
|
||||
window_class->update_icon = meta_window_x11_update_icon;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1606,6 +1587,167 @@ meta_window_x11_set_net_wm_state (MetaWindow *window)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_x11_update_net_wm_type (MetaWindow *window)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
int n_atoms;
|
||||
Atom *atoms;
|
||||
int i;
|
||||
|
||||
priv->type_atom = None;
|
||||
n_atoms = 0;
|
||||
atoms = NULL;
|
||||
|
||||
meta_prop_get_atom_list (window->display, window->xwindow,
|
||||
window->display->atom__NET_WM_WINDOW_TYPE,
|
||||
&atoms, &n_atoms);
|
||||
|
||||
i = 0;
|
||||
while (i < n_atoms)
|
||||
{
|
||||
/* We break as soon as we find one we recognize,
|
||||
* supposed to prefer those near the front of the list
|
||||
*/
|
||||
if (atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP ||
|
||||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DOCK ||
|
||||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR ||
|
||||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_MENU ||
|
||||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY ||
|
||||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH ||
|
||||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG ||
|
||||
atoms[i] ==
|
||||
window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU ||
|
||||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU ||
|
||||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP ||
|
||||
atoms[i] ==
|
||||
window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION ||
|
||||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_COMBO ||
|
||||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DND ||
|
||||
atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL)
|
||||
{
|
||||
priv->type_atom = atoms[i];
|
||||
break;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
meta_XFree (atoms);
|
||||
|
||||
if (meta_is_verbose ())
|
||||
{
|
||||
char *str;
|
||||
|
||||
str = NULL;
|
||||
if (priv->type_atom != None)
|
||||
{
|
||||
meta_error_trap_push (window->display);
|
||||
str = XGetAtomName (window->display->xdisplay, priv->type_atom);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
meta_verbose ("Window %s type atom %s\n", window->desc,
|
||||
str ? str : "(none)");
|
||||
|
||||
if (str)
|
||||
meta_XFree (str);
|
||||
}
|
||||
|
||||
meta_window_x11_recalc_window_type (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_x11_update_role (MetaWindow *window)
|
||||
{
|
||||
char *str;
|
||||
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
if (window->role)
|
||||
g_free (window->role);
|
||||
window->role = NULL;
|
||||
|
||||
if (meta_prop_get_latin1_string (window->display, window->xwindow,
|
||||
window->display->atom_WM_WINDOW_ROLE,
|
||||
&str))
|
||||
{
|
||||
window->role = g_strdup (str);
|
||||
meta_XFree (str);
|
||||
}
|
||||
|
||||
meta_verbose ("Updated role of %s to '%s'\n",
|
||||
window->desc, window->role ? window->role : "null");
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_set_opaque_region (MetaWindow *window,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
g_clear_pointer (&window->opaque_region, cairo_region_destroy);
|
||||
|
||||
if (region != NULL)
|
||||
window->opaque_region = cairo_region_reference (region);
|
||||
|
||||
meta_compositor_window_shape_changed (window->display->compositor, window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_x11_update_opaque_region (MetaWindow *window)
|
||||
{
|
||||
cairo_region_t *opaque_region = NULL;
|
||||
gulong *region = NULL;
|
||||
int nitems;
|
||||
|
||||
if (meta_prop_get_cardinal_list (window->display,
|
||||
window->xwindow,
|
||||
window->display->atom__NET_WM_OPAQUE_REGION,
|
||||
®ion, &nitems))
|
||||
{
|
||||
cairo_rectangle_int_t *rects;
|
||||
int i, rect_index, nrects;
|
||||
|
||||
if (nitems % 4 != 0)
|
||||
{
|
||||
meta_verbose ("_NET_WM_OPAQUE_REGION does not have a list of 4-tuples.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* empty region */
|
||||
if (nitems == 0)
|
||||
goto out;
|
||||
|
||||
nrects = nitems / 4;
|
||||
|
||||
rects = g_new (cairo_rectangle_int_t, nrects);
|
||||
|
||||
rect_index = 0;
|
||||
i = 0;
|
||||
while (i < nitems)
|
||||
{
|
||||
cairo_rectangle_int_t *rect = &rects[rect_index];
|
||||
|
||||
rect->x = region[i++];
|
||||
rect->y = region[i++];
|
||||
rect->width = region[i++];
|
||||
rect->height = region[i++];
|
||||
|
||||
rect_index++;
|
||||
}
|
||||
|
||||
opaque_region = cairo_region_create_rectangles (rects, nrects);
|
||||
|
||||
g_free (rects);
|
||||
}
|
||||
|
||||
out:
|
||||
meta_XFree (region);
|
||||
|
||||
meta_window_set_opaque_region (window, opaque_region);
|
||||
cairo_region_destroy (opaque_region);
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
region_create_from_x_rectangles (const XRectangle *rects,
|
||||
int n_rects)
|
||||
@@ -1628,9 +1770,6 @@ static void
|
||||
meta_window_set_input_region (MetaWindow *window,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
if (cairo_region_equal (window->input_region, region))
|
||||
return;
|
||||
|
||||
g_clear_pointer (&window->input_region, cairo_region_destroy);
|
||||
|
||||
if (region != NULL)
|
||||
@@ -1737,9 +1876,6 @@ static void
|
||||
meta_window_set_shape_region (MetaWindow *window,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
if (cairo_region_equal (window->shape_region, region))
|
||||
return;
|
||||
|
||||
g_clear_pointer (&window->shape_region, cairo_region_destroy);
|
||||
|
||||
if (region != NULL)
|
||||
@@ -2797,7 +2933,7 @@ is_our_xwindow (MetaDisplay *display,
|
||||
if (xwindow == screen->guard_window)
|
||||
return TRUE;
|
||||
|
||||
if (xwindow == screen->composite_overlay_window)
|
||||
if (xwindow == XCompositeGetOverlayWindow (display->xdisplay, screen->xroot))
|
||||
return TRUE;
|
||||
|
||||
/* Any windows created via meta_create_offscreen_window */
|
||||
@@ -2929,6 +3065,8 @@ meta_window_x11_new (MetaDisplay *display,
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
|
||||
meta_core_add_old_event_mask (display->xdisplay, xwindow, &mask);
|
||||
|
||||
XISetMask (mask.mask, XI_Enter);
|
||||
XISetMask (mask.mask, XI_Leave);
|
||||
XISetMask (mask.mask, XI_FocusIn);
|
||||
@@ -2985,6 +3123,8 @@ meta_window_x11_new (MetaDisplay *display,
|
||||
meta_display_grab_focus_window_button (window->display, window);
|
||||
}
|
||||
|
||||
meta_window_set_surface_mapped (window, TRUE);
|
||||
|
||||
meta_error_trap_pop (display); /* pop the XSync()-reducing trap */
|
||||
return window;
|
||||
|
||||
|
@@ -55,6 +55,9 @@ void meta_window_x11_destroy_sync_request_alarm (MetaWindow *window);
|
||||
void meta_window_x11_update_sync_request_counter (MetaWindow *window,
|
||||
gint64 new_counter_value);
|
||||
|
||||
void meta_window_x11_update_role (MetaWindow *window);
|
||||
void meta_window_x11_update_net_wm_type (MetaWindow *window);
|
||||
void meta_window_x11_update_opaque_region (MetaWindow *window);
|
||||
void meta_window_x11_update_input_region (MetaWindow *window);
|
||||
void meta_window_x11_update_shape_region (MetaWindow *window);
|
||||
|
||||
|
Reference in New Issue
Block a user