Compare commits
45 Commits
3.10.0-way
...
wip/waylan
Author | SHA1 | Date | |
---|---|---|---|
![]() |
531a7b2812 | ||
![]() |
580669cdea | ||
![]() |
e50a578ad3 | ||
![]() |
06b3d36e97 | ||
![]() |
715fa91599 | ||
![]() |
997188e914 | ||
![]() |
c6dd56f9ce | ||
![]() |
466af03ed3 | ||
![]() |
9c2d806556 | ||
![]() |
13a7c8da85 | ||
![]() |
d69d566087 | ||
![]() |
b722274886 | ||
![]() |
164cdabb21 | ||
![]() |
0b025f0e9c | ||
![]() |
87354bdac6 | ||
![]() |
02e163882a | ||
![]() |
9db02a7379 | ||
![]() |
78fcfec5c1 | ||
![]() |
1bd3a162f8 | ||
![]() |
918cfdcbda | ||
![]() |
cd76313297 | ||
![]() |
dc8231c2cf | ||
![]() |
4d01eb3a23 | ||
![]() |
35f47b211d | ||
![]() |
77046edf21 | ||
![]() |
488df061c7 | ||
![]() |
21d511e50f | ||
![]() |
15e83f0c2f | ||
![]() |
a23830fd13 | ||
![]() |
c8bf8c17be | ||
![]() |
d82e24981b | ||
![]() |
01b8ffac5d | ||
![]() |
1fa56bd7e0 | ||
![]() |
c3f28b9cdb | ||
![]() |
dc4e1d4cd1 | ||
![]() |
d69553e8f5 | ||
![]() |
0ead0d945a | ||
![]() |
c24d9bf142 | ||
![]() |
a6bf340ff8 | ||
![]() |
35ef7c95b2 | ||
![]() |
348f3007d9 | ||
![]() |
52e2a1226e | ||
![]() |
58622c0515 | ||
![]() |
cb5e1e2776 | ||
![]() |
e965cf32d4 |
@@ -6,3 +6,5 @@ EXTRA_DIST = HACKING MAINTAINERS rationales.txt
|
|||||||
DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache
|
DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache
|
||||||
|
|
||||||
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
|
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
|
||||||
|
|
||||||
|
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||||
|
30
NEWS
30
NEWS
@@ -1,3 +1,33 @@
|
|||||||
|
3.11.1
|
||||||
|
======
|
||||||
|
* Fix tile previews getting stuck on right click during drags [Lionel; #704759]
|
||||||
|
* Use new UPower API [Bastien]
|
||||||
|
* Set hot spot when cursor set from wl_buffer [Jonas; #709593]
|
||||||
|
* Expose min-backlight-step [Asad; #710380]
|
||||||
|
* Misc. bug fixes and cleanups [Jasper, Olav, Magdalen; #709776]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Magdalen Berns, Lionel Landwerlin, Asad Mehmood, Bastien Nocera,
|
||||||
|
Jasper St. Pierre, Olav Vitters, Jonas Ådahl
|
||||||
|
|
||||||
|
3.10.1
|
||||||
|
======
|
||||||
|
* Don't apply fullscreen workarounds to CSD windows [Giovanni; #708718]
|
||||||
|
* Fix hangs during DND operations [Adel; #709340]
|
||||||
|
* Misc bug fixes [Dan, Giovanni, Jasper; #708813, #708420]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Adel Gadllah, Dan Horák, Hans Petter Jansson,
|
||||||
|
Jasper St. Pierre
|
||||||
|
|
||||||
|
3.10.0.1
|
||||||
|
========
|
||||||
|
* Fix bug when a window changed size twice in a single frame - this
|
||||||
|
can happen with GTK+ client-side decorations [Giovanni, Owen; #708367]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Owen Taylor
|
||||||
|
|
||||||
3.10.0
|
3.10.0
|
||||||
======
|
======
|
||||||
* Update dependencies [Giovanni; #708210]
|
* Update dependencies [Giovanni; #708210]
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
AC_PREREQ(2.50)
|
AC_PREREQ(2.50)
|
||||||
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
m4_define([mutter_major_version], [3])
|
m4_define([mutter_major_version], [3])
|
||||||
m4_define([mutter_minor_version], [10])
|
m4_define([mutter_minor_version], [11])
|
||||||
m4_define([mutter_micro_version], [0])
|
m4_define([mutter_micro_version], [1])
|
||||||
|
|
||||||
m4_define([mutter_version],
|
m4_define([mutter_version],
|
||||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||||
@@ -79,7 +80,7 @@ MUTTER_PC_MODULES="
|
|||||||
xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0
|
xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0
|
||||||
$CLUTTER_PACKAGE >= 1.15.94
|
$CLUTTER_PACKAGE >= 1.15.94
|
||||||
cogl-1.0 >= 1.13.3
|
cogl-1.0 >= 1.13.3
|
||||||
upower-glib > 0.9.11
|
upower-glib >= 0.99.0
|
||||||
gnome-desktop-3.0
|
gnome-desktop-3.0
|
||||||
"
|
"
|
||||||
|
|
||||||
|
@@ -207,7 +207,6 @@ meta_key_binding_get_modifiers
|
|||||||
meta_key_binding_get_mask
|
meta_key_binding_get_mask
|
||||||
meta_key_binding_is_builtin
|
meta_key_binding_is_builtin
|
||||||
meta_keybindings_set_custom_handler
|
meta_keybindings_set_custom_handler
|
||||||
meta_keybindings_switch_window
|
|
||||||
meta_screen_ungrab_all_keys
|
meta_screen_ungrab_all_keys
|
||||||
meta_screen_grab_all_keys
|
meta_screen_grab_all_keys
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
@@ -21,6 +21,7 @@ environment.</description>
|
|||||||
-->
|
-->
|
||||||
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" />
|
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" />
|
||||||
<download-page rdf:resource="http://download.gnome.org/sources/mutter/" />
|
<download-page rdf:resource="http://download.gnome.org/sources/mutter/" />
|
||||||
|
<download-page rdf:resource="http://download.gnome.org/sources/mutter-wayland/" />
|
||||||
<bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=mutter" />
|
<bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=mutter" />
|
||||||
|
|
||||||
<category rdf:resource="http://api.gnome.org/doap-extensions#desktop" />
|
<category rdf:resource="http://api.gnome.org/doap-extensions#desktop" />
|
||||||
|
@@ -395,7 +395,6 @@ $(dbus_xrandr_built_sources) : Makefile.am xrandr.xml
|
|||||||
--generate-c-code meta-dbus-xrandr \
|
--generate-c-code meta-dbus-xrandr \
|
||||||
$(srcdir)/xrandr.xml
|
$(srcdir)/xrandr.xml
|
||||||
|
|
||||||
dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h
|
|
||||||
|
|
||||||
$(dbus_idle_built_sources) : Makefile.am idle-monitor.xml
|
$(dbus_idle_built_sources) : Makefile.am idle-monitor.xml
|
||||||
$(AM_V_GEN)gdbus-codegen \
|
$(AM_V_GEN)gdbus-codegen \
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include <meta/meta-shaped-texture.h>
|
#include <meta/meta-shaped-texture.h>
|
||||||
#include <meta/util.h>
|
#include <meta/util.h>
|
||||||
|
#include "clutter-utils.h"
|
||||||
#include "meta-texture-tower.h"
|
#include "meta-texture-tower.h"
|
||||||
|
|
||||||
#include "meta-shaped-texture-private.h"
|
#include "meta-shaped-texture-private.h"
|
||||||
@@ -280,6 +281,7 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|||||||
CoglTexture *paint_tex;
|
CoglTexture *paint_tex;
|
||||||
ClutterActorBox alloc;
|
ClutterActorBox alloc;
|
||||||
cairo_region_t *blended_region = NULL;
|
cairo_region_t *blended_region = NULL;
|
||||||
|
CoglPipelineFilter filter;
|
||||||
|
|
||||||
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
|
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
|
||||||
return;
|
return;
|
||||||
@@ -316,6 +318,22 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|||||||
if (tex_width == 0 || tex_height == 0) /* no contents yet */
|
if (tex_width == 0 || tex_height == 0) /* no contents yet */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Use nearest-pixel interpolation if the texture is unscaled. This
|
||||||
|
* improves performance, especially with software rendering.
|
||||||
|
*/
|
||||||
|
|
||||||
|
filter = COGL_PIPELINE_FILTER_LINEAR;
|
||||||
|
|
||||||
|
if (!clutter_actor_is_in_clone_paint (actor))
|
||||||
|
{
|
||||||
|
int x_origin, y_origin;
|
||||||
|
|
||||||
|
if (meta_actor_is_untransformed (actor,
|
||||||
|
&x_origin,
|
||||||
|
&y_origin))
|
||||||
|
filter = COGL_PIPELINE_FILTER_NEAREST;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||||
fb = cogl_get_draw_framebuffer ();
|
fb = cogl_get_draw_framebuffer ();
|
||||||
|
|
||||||
@@ -344,6 +362,7 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|||||||
|
|
||||||
opaque_pipeline = get_unblended_pipeline (ctx);
|
opaque_pipeline = get_unblended_pipeline (ctx);
|
||||||
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
|
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
|
||||||
|
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
|
||||||
|
|
||||||
n_rects = cairo_region_num_rectangles (region);
|
n_rects = cairo_region_num_rectangles (region);
|
||||||
for (i = 0; i < n_rects; i++)
|
for (i = 0; i < n_rects; i++)
|
||||||
@@ -385,9 +404,11 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|||||||
{
|
{
|
||||||
pipeline = get_masked_pipeline (ctx);
|
pipeline = get_masked_pipeline (ctx);
|
||||||
cogl_pipeline_set_layer_texture (pipeline, 1, priv->mask_texture);
|
cogl_pipeline_set_layer_texture (pipeline, 1, priv->mask_texture);
|
||||||
|
cogl_pipeline_set_layer_filters (pipeline, 1, filter, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
cogl_pipeline_set_layer_texture (pipeline, 0, paint_tex);
|
cogl_pipeline_set_layer_texture (pipeline, 0, paint_tex);
|
||||||
|
cogl_pipeline_set_layer_filters (pipeline, 0, filter, filter);
|
||||||
|
|
||||||
{
|
{
|
||||||
CoglColor color;
|
CoglColor color;
|
||||||
|
@@ -1007,7 +1007,7 @@ queue_send_frame_messages_timeout (MetaWindowActor *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
interval = (int)(1000000 / refresh_rate) * 6;
|
interval = (int)(1000000 / refresh_rate) * 6;
|
||||||
offset = MAX (0, current_time - priv->frame_drawn_time + interval) / 1000;
|
offset = MAX (0, priv->frame_drawn_time + interval - current_time) / 1000;
|
||||||
|
|
||||||
/* The clutter master clock source has already been added with META_PRIORITY_REDRAW,
|
/* The clutter master clock source has already been added with META_PRIORITY_REDRAW,
|
||||||
* so the timer will run *after* the clutter frame handling, if a frame is ready
|
* so the timer will run *after* the clutter frame handling, if a frame is ready
|
||||||
@@ -1473,6 +1473,22 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
|
|||||||
MetaWindowActorPrivate *priv = self->priv;
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
MetaRectangle window_rect;
|
MetaRectangle window_rect;
|
||||||
|
|
||||||
|
meta_window_get_input_rect (priv->window, &window_rect);
|
||||||
|
|
||||||
|
/* When running as a display server we catch size changes when new
|
||||||
|
buffers are attached */
|
||||||
|
if (!meta_is_wayland_compositor ())
|
||||||
|
{
|
||||||
|
if (priv->last_width != window_rect.width ||
|
||||||
|
priv->last_height != window_rect.height)
|
||||||
|
{
|
||||||
|
priv->x11_size_changed = TRUE;
|
||||||
|
|
||||||
|
priv->last_width = window_rect.width;
|
||||||
|
priv->last_height = window_rect.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Normally we want freezing a window to also freeze its position; this allows
|
/* Normally we want freezing a window to also freeze its position; this allows
|
||||||
* windows to atomically move and resize together, either under app control,
|
* windows to atomically move and resize together, either under app control,
|
||||||
* or because the user is resizing from the left/top. But on initial placement
|
* or because the user is resizing from the left/top. But on initial placement
|
||||||
@@ -1483,22 +1499,12 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
|
|||||||
if (is_frozen (self) && !did_placement)
|
if (is_frozen (self) && !did_placement)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
meta_window_get_input_rect (priv->window, &window_rect);
|
|
||||||
|
|
||||||
/* When running as a display server then we instead catch size changes when
|
|
||||||
* new buffers are attached */
|
|
||||||
if (!meta_is_wayland_compositor ())
|
if (!meta_is_wayland_compositor ())
|
||||||
{
|
{
|
||||||
if (priv->last_width != window_rect.width ||
|
if (priv->x11_size_changed)
|
||||||
priv->last_height != window_rect.height)
|
|
||||||
{
|
{
|
||||||
priv->x11_size_changed = TRUE;
|
|
||||||
meta_window_actor_queue_create_x11_pixmap (self);
|
meta_window_actor_queue_create_x11_pixmap (self);
|
||||||
|
|
||||||
meta_window_actor_update_shape (self);
|
meta_window_actor_update_shape (self);
|
||||||
|
|
||||||
priv->last_width = window_rect.width;
|
|
||||||
priv->last_height = window_rect.height;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -366,11 +366,25 @@ meta_barrier_fire_event (MetaBarrier *barrier,
|
|||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_display_process_barrier_event (MetaDisplay *display,
|
meta_display_process_barrier_event (MetaDisplay *display,
|
||||||
XIBarrierEvent *xev)
|
XIEvent *event)
|
||||||
{
|
{
|
||||||
MetaBarrier *barrier;
|
MetaBarrier *barrier;
|
||||||
|
XIBarrierEvent *xev;
|
||||||
|
|
||||||
|
if (event == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (event->evtype)
|
||||||
|
{
|
||||||
|
case XI_BarrierHit:
|
||||||
|
case XI_BarrierLeave:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xev = (XIBarrierEvent *) event;
|
||||||
barrier = g_hash_table_lookup (display->xids, &xev->barrier);
|
barrier = g_hash_table_lookup (display->xids, &xev->barrier);
|
||||||
if (barrier != NULL)
|
if (barrier != NULL)
|
||||||
{
|
{
|
||||||
|
@@ -447,12 +447,14 @@ setup_constraint_info (ConstraintInfo *info,
|
|||||||
|
|
||||||
/* Workaround braindead legacy apps that don't know how to
|
/* Workaround braindead legacy apps that don't know how to
|
||||||
* fullscreen themselves properly - don't get fooled by
|
* fullscreen themselves properly - don't get fooled by
|
||||||
* windows which hide their titlebar when maximized; that's
|
* windows which hide their titlebar when maximized or which are
|
||||||
* not the same as fullscreen, even if there are no struts
|
* client decorated; that's not the same as fullscreen, even
|
||||||
* making the workarea smaller than the monitor.
|
* if there are no struts making the workarea smaller than
|
||||||
|
* the monitor.
|
||||||
*/
|
*/
|
||||||
if (meta_prefs_get_force_fullscreen() &&
|
if (meta_prefs_get_force_fullscreen() &&
|
||||||
!window->hide_titlebar_when_maximized &&
|
!window->hide_titlebar_when_maximized &&
|
||||||
|
window->decorated &&
|
||||||
meta_rectangle_equal (new, &monitor_info->rect) &&
|
meta_rectangle_equal (new, &monitor_info->rect) &&
|
||||||
window->has_fullscreen_func &&
|
window->has_fullscreen_func &&
|
||||||
!window->fullscreen)
|
!window->fullscreen)
|
||||||
|
@@ -476,26 +476,6 @@ meta_core_change_workspace (Display *xdisplay,
|
|||||||
new_workspace));
|
new_workspace));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
meta_core_get_num_workspaces (Screen *xscreen)
|
|
||||||
{
|
|
||||||
MetaScreen *screen;
|
|
||||||
|
|
||||||
screen = meta_screen_for_x_screen (xscreen);
|
|
||||||
|
|
||||||
return meta_screen_get_n_workspaces (screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
meta_core_get_active_workspace (Screen *xscreen)
|
|
||||||
{
|
|
||||||
MetaScreen *screen;
|
|
||||||
|
|
||||||
screen = meta_screen_for_x_screen (xscreen);
|
|
||||||
|
|
||||||
return meta_workspace_index (screen->active_workspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_core_show_window_menu (Display *xdisplay,
|
meta_core_show_window_menu (Display *xdisplay,
|
||||||
Window frame_xwindow,
|
Window frame_xwindow,
|
||||||
|
@@ -153,8 +153,6 @@ void meta_core_change_workspace (Display *xdisplay,
|
|||||||
Window frame_xwindow,
|
Window frame_xwindow,
|
||||||
int new_workspace);
|
int new_workspace);
|
||||||
|
|
||||||
int meta_core_get_num_workspaces (Screen *xscreen);
|
|
||||||
int meta_core_get_active_workspace (Screen *xscreen);
|
|
||||||
int meta_core_get_frame_workspace (Display *xdisplay,
|
int meta_core_get_frame_workspace (Display *xdisplay,
|
||||||
Window frame_xwindow);
|
Window frame_xwindow);
|
||||||
const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
|
const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
#include "keybindings-private.h"
|
#include "keybindings-private.h"
|
||||||
#include <meta/prefs.h>
|
#include <meta/prefs.h>
|
||||||
#include <meta/barrier.h>
|
#include <meta/barrier.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||||
#include <libsn/sn.h>
|
#include <libsn/sn.h>
|
||||||
@@ -189,7 +190,7 @@ struct _MetaDisplay
|
|||||||
MetaWindow* autoraise_window;
|
MetaWindow* autoraise_window;
|
||||||
|
|
||||||
/* Alt+click button grabs */
|
/* Alt+click button grabs */
|
||||||
unsigned int window_grab_modifiers;
|
ClutterModifierType window_grab_modifiers;
|
||||||
|
|
||||||
/* current window operation */
|
/* current window operation */
|
||||||
MetaGrabOp grab_op;
|
MetaGrabOp grab_op;
|
||||||
@@ -473,21 +474,23 @@ void meta_display_queue_autoraise_callback (MetaDisplay *display,
|
|||||||
void meta_display_remove_autoraise_callback (MetaDisplay *display);
|
void meta_display_remove_autoraise_callback (MetaDisplay *display);
|
||||||
|
|
||||||
void meta_display_overlay_key_activate (MetaDisplay *display);
|
void meta_display_overlay_key_activate (MetaDisplay *display);
|
||||||
void meta_display_accelerator_activate (MetaDisplay *display,
|
void meta_display_accelerator_activate (MetaDisplay *display,
|
||||||
guint action,
|
guint action,
|
||||||
guint deviceid,
|
ClutterKeyEvent *event);
|
||||||
guint timestamp);
|
|
||||||
gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display);
|
gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display);
|
||||||
|
|
||||||
/* In above-tab-keycode.c */
|
/* In above-tab-keycode.c */
|
||||||
guint meta_display_get_above_tab_keycode (MetaDisplay *display);
|
guint meta_display_get_above_tab_keycode (MetaDisplay *display);
|
||||||
|
|
||||||
gboolean meta_display_handle_event (MetaDisplay *display,
|
gboolean meta_display_handle_xevent (MetaDisplay *display,
|
||||||
XEvent *event);
|
XEvent *event);
|
||||||
|
|
||||||
|
gboolean meta_display_handle_event (MetaDisplay *display,
|
||||||
|
const ClutterEvent *event);
|
||||||
|
|
||||||
#ifdef HAVE_XI23
|
#ifdef HAVE_XI23
|
||||||
gboolean meta_display_process_barrier_event (MetaDisplay *display,
|
gboolean meta_display_process_barrier_event (MetaDisplay *display,
|
||||||
XIBarrierEvent *event);
|
XIEvent *event);
|
||||||
#endif /* HAVE_XI23 */
|
#endif /* HAVE_XI23 */
|
||||||
|
|
||||||
void meta_display_set_input_focus_xwindow (MetaDisplay *display,
|
void meta_display_set_input_focus_xwindow (MetaDisplay *display,
|
||||||
|
2255
src/core/display.c
2255
src/core/display.c
File diff suppressed because it is too large
Load Diff
@@ -66,9 +66,9 @@ gboolean meta_window_grab_all_keys (MetaWindow *window,
|
|||||||
guint32 timestamp);
|
guint32 timestamp);
|
||||||
void meta_window_ungrab_all_keys (MetaWindow *window,
|
void meta_window_ungrab_all_keys (MetaWindow *window,
|
||||||
guint32 timestamp);
|
guint32 timestamp);
|
||||||
gboolean meta_display_process_key_event (MetaDisplay *display,
|
gboolean meta_display_process_key_event (MetaDisplay *display,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
XIDeviceEvent *event);
|
ClutterKeyEvent *event);
|
||||||
void meta_display_process_mapping_event (MetaDisplay *display,
|
void meta_display_process_mapping_event (MetaDisplay *display,
|
||||||
XEvent *event);
|
XEvent *event);
|
||||||
|
|
||||||
@@ -81,7 +81,3 @@ gboolean meta_prefs_remove_keybinding (const char *name);
|
|||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
|
|
||||||
|
#include <X11/cursorfont.h>
|
||||||
#include <X11/extensions/Xfixes.h>
|
#include <X11/extensions/Xfixes.h>
|
||||||
#include <X11/Xcursor/Xcursor.h>
|
#include <X11/Xcursor/Xcursor.h>
|
||||||
|
|
||||||
@@ -128,76 +129,130 @@ meta_cursor_reference_unref (MetaCursorReference *self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static void
|
||||||
get_cursor_filename (MetaCursor cursor)
|
translate_meta_cursor (MetaCursor cursor,
|
||||||
|
guint *glyph_out,
|
||||||
|
const char **name_out)
|
||||||
{
|
{
|
||||||
|
guint glyph = XC_num_glyphs;
|
||||||
|
const char *name = NULL;
|
||||||
|
|
||||||
switch (cursor)
|
switch (cursor)
|
||||||
{
|
{
|
||||||
case META_CURSOR_DEFAULT:
|
case META_CURSOR_DEFAULT:
|
||||||
return "left_ptr";
|
glyph = XC_left_ptr;
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_NORTH_RESIZE:
|
case META_CURSOR_NORTH_RESIZE:
|
||||||
return "top_side";
|
glyph = XC_top_side;
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_SOUTH_RESIZE:
|
case META_CURSOR_SOUTH_RESIZE:
|
||||||
return "bottom_side";
|
glyph = XC_bottom_side;
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_WEST_RESIZE:
|
case META_CURSOR_WEST_RESIZE:
|
||||||
return "left_side";
|
glyph = XC_left_side;
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_EAST_RESIZE:
|
case META_CURSOR_EAST_RESIZE:
|
||||||
return "right_side";
|
glyph = XC_right_side;
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_SE_RESIZE:
|
case META_CURSOR_SE_RESIZE:
|
||||||
return "bottom_right_corner";
|
glyph = XC_bottom_right_corner;
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_SW_RESIZE:
|
case META_CURSOR_SW_RESIZE:
|
||||||
return "bottom_left_corner";
|
glyph = XC_bottom_left_corner;
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_NE_RESIZE:
|
case META_CURSOR_NE_RESIZE:
|
||||||
return "top_right_corner";
|
glyph = XC_top_right_corner;
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_NW_RESIZE:
|
case META_CURSOR_NW_RESIZE:
|
||||||
return "top_left_corner";
|
glyph = XC_top_left_corner;
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
|
case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
|
||||||
return "fleur";
|
glyph = XC_fleur;
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_BUSY:
|
case META_CURSOR_BUSY:
|
||||||
return "watch";
|
glyph = XC_watch;
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_DND_IN_DRAG:
|
case META_CURSOR_DND_IN_DRAG:
|
||||||
return "dnd-in-drag";
|
name = "dnd-none";
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_DND_MOVE:
|
case META_CURSOR_DND_MOVE:
|
||||||
return "dnd-copy";
|
name = "dnd-move";
|
||||||
|
break;
|
||||||
|
case META_CURSOR_DND_COPY:
|
||||||
|
name = "dnd-copy";
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_DND_UNSUPPORTED_TARGET:
|
case META_CURSOR_DND_UNSUPPORTED_TARGET:
|
||||||
return "dnd-none";
|
name = "dnd-none";
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_POINTING_HAND:
|
case META_CURSOR_POINTING_HAND:
|
||||||
return "hand";
|
glyph = XC_hand2;
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_CROSSHAIR:
|
case META_CURSOR_CROSSHAIR:
|
||||||
return "crosshair";
|
glyph = XC_crosshair;
|
||||||
break;
|
break;
|
||||||
case META_CURSOR_IBEAM:
|
case META_CURSOR_IBEAM:
|
||||||
return "xterm";
|
glyph = XC_xterm;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
return NULL;
|
glyph = 0; /* silence compiler */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*glyph_out = glyph;
|
||||||
|
*name_out = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Cursor
|
||||||
|
load_cursor_on_server (MetaDisplay *display,
|
||||||
|
MetaCursor cursor)
|
||||||
|
{
|
||||||
|
Cursor xcursor;
|
||||||
|
guint glyph;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
translate_meta_cursor (cursor, &glyph, &name);
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
xcursor = XcursorLibraryLoadCursor (display->xdisplay, name);
|
||||||
|
else
|
||||||
|
xcursor = XCreateFontCursor (display->xdisplay, glyph);
|
||||||
|
|
||||||
|
return xcursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cursor
|
||||||
|
meta_display_create_x_cursor (MetaDisplay *display,
|
||||||
|
MetaCursor cursor)
|
||||||
|
{
|
||||||
|
return load_cursor_on_server (display, cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static XcursorImage *
|
||||||
|
load_cursor_on_client (MetaDisplay *display,
|
||||||
|
MetaCursor cursor)
|
||||||
|
{
|
||||||
|
XcursorImage *image;
|
||||||
|
guint glyph;
|
||||||
|
const char *name;
|
||||||
|
const char *theme = XcursorGetTheme (display->xdisplay);
|
||||||
|
int size = XcursorGetDefaultSize (display->xdisplay);
|
||||||
|
|
||||||
|
translate_meta_cursor (cursor, &glyph, &name);
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
image = XcursorLibraryLoadImage (name, theme, size);
|
||||||
|
else
|
||||||
|
image = XcursorShapeLoadImage (glyph, theme, size);
|
||||||
|
|
||||||
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaCursorReference *
|
static MetaCursorReference *
|
||||||
meta_cursor_reference_from_theme (MetaCursorTracker *tracker,
|
meta_cursor_reference_from_theme (MetaCursorTracker *tracker,
|
||||||
MetaCursor cursor)
|
MetaCursor cursor)
|
||||||
{
|
{
|
||||||
const char *theme;
|
|
||||||
const char *filename;
|
|
||||||
int size;
|
|
||||||
XcursorImage *image;
|
XcursorImage *image;
|
||||||
int width, height, rowstride;
|
int width, height, rowstride;
|
||||||
CoglPixelFormat cogl_format;
|
CoglPixelFormat cogl_format;
|
||||||
@@ -206,11 +261,7 @@ meta_cursor_reference_from_theme (MetaCursorTracker *tracker,
|
|||||||
CoglContext *cogl_context;
|
CoglContext *cogl_context;
|
||||||
MetaCursorReference *self;
|
MetaCursorReference *self;
|
||||||
|
|
||||||
filename = get_cursor_filename (cursor);
|
image = load_cursor_on_client (tracker->screen->display, cursor);
|
||||||
theme = XcursorGetTheme (tracker->screen->display->xdisplay);
|
|
||||||
size = XcursorGetDefaultSize (tracker->screen->display->xdisplay);
|
|
||||||
|
|
||||||
image = XcursorLibraryLoadImage (filename, theme, size);
|
|
||||||
if (!image)
|
if (!image)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -301,6 +352,8 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
|
|||||||
|
|
||||||
self = g_slice_new0 (MetaCursorReference);
|
self = g_slice_new0 (MetaCursorReference);
|
||||||
self->ref_count = 1;
|
self->ref_count = 1;
|
||||||
|
self->hot_x = hot_x;
|
||||||
|
self->hot_y = hot_y;
|
||||||
|
|
||||||
backend = clutter_get_default_backend ();
|
backend = clutter_get_default_backend ();
|
||||||
cogl_context = clutter_backend_get_cogl_context (backend);
|
cogl_context = clutter_backend_get_cogl_context (backend);
|
||||||
@@ -320,7 +373,7 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
|
|||||||
cogl_internal_format = COGL_PIXEL_FORMAT_ANY;
|
cogl_internal_format = COGL_PIXEL_FORMAT_ANY;
|
||||||
gbm_format = GBM_FORMAT_ARGB8888;
|
gbm_format = GBM_FORMAT_ARGB8888;
|
||||||
break;
|
break;
|
||||||
case WL_SHM_FORMAT_XRGB32:
|
case WL_SHM_FORMAT_XRGB8888:
|
||||||
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
|
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||||
cogl_internal_format = COGL_PIXEL_FORMAT_RGB_888;
|
cogl_internal_format = COGL_PIXEL_FORMAT_RGB_888;
|
||||||
gbm_format = GBM_FORMAT_XRGB8888;
|
gbm_format = GBM_FORMAT_XRGB8888;
|
||||||
|
@@ -293,6 +293,7 @@ idle_monitor_watch_free (MetaIdleMonitorWatch *watch)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
monitor = watch->monitor;
|
monitor = watch->monitor;
|
||||||
|
g_object_ref (monitor);
|
||||||
|
|
||||||
if (watch->idle_source_id)
|
if (watch->idle_source_id)
|
||||||
{
|
{
|
||||||
@@ -313,6 +314,7 @@ idle_monitor_watch_free (MetaIdleMonitorWatch *watch)
|
|||||||
if (watch->timeout_source != NULL)
|
if (watch->timeout_source != NULL)
|
||||||
g_source_destroy (watch->timeout_source);
|
g_source_destroy (watch->timeout_source);
|
||||||
|
|
||||||
|
g_object_unref (monitor);
|
||||||
g_slice_free (MetaIdleMonitorWatch, watch);
|
g_slice_free (MetaIdleMonitorWatch, watch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -99,8 +99,9 @@ static gboolean meta_monitor_config_assign_crtcs (MetaConfiguration *config,
|
|||||||
GPtrArray *crtcs,
|
GPtrArray *crtcs,
|
||||||
GPtrArray *outputs);
|
GPtrArray *outputs);
|
||||||
|
|
||||||
static void power_client_changed_cb (UpClient *client,
|
static void power_client_changed_cb (UpClient *client,
|
||||||
gpointer user_data);
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_output_key (MetaOutputKey *key)
|
free_output_key (MetaOutputKey *key)
|
||||||
@@ -232,7 +233,7 @@ meta_monitor_config_init (MetaMonitorConfig *self)
|
|||||||
self->up_client = up_client_new ();
|
self->up_client = up_client_new ();
|
||||||
self->lid_is_closed = up_client_get_lid_is_closed (self->up_client);
|
self->lid_is_closed = up_client_get_lid_is_closed (self->up_client);
|
||||||
|
|
||||||
g_signal_connect_object (self->up_client, "changed",
|
g_signal_connect_object (self->up_client, "notify::lid-is-closed",
|
||||||
G_CALLBACK (power_client_changed_cb), self, 0);
|
G_CALLBACK (power_client_changed_cb), self, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1335,8 +1336,9 @@ turn_off_laptop_display (MetaMonitorConfig *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
power_client_changed_cb (UpClient *client,
|
power_client_changed_cb (UpClient *client,
|
||||||
gpointer user_data)
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaMonitorManager *manager = meta_monitor_manager_get ();
|
MetaMonitorManager *manager = meta_monitor_manager_get ();
|
||||||
MetaMonitorConfig *self = user_data;
|
MetaMonitorConfig *self = user_data;
|
||||||
|
@@ -729,6 +729,9 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
|||||||
g_variant_new_take_string (make_display_name (manager, output)));
|
g_variant_new_take_string (make_display_name (manager, output)));
|
||||||
g_variant_builder_add (&properties, "{sv}", "backlight",
|
g_variant_builder_add (&properties, "{sv}", "backlight",
|
||||||
g_variant_new_int32 (output->backlight));
|
g_variant_new_int32 (output->backlight));
|
||||||
|
g_variant_builder_add (&properties, "{sv}", "min-backlight-step",
|
||||||
|
g_variant_new_int32 ((output->backlight_max - output->backlight_min) ?
|
||||||
|
100 / (output->backlight_max - output->backlight_min) : -1));
|
||||||
g_variant_builder_add (&properties, "{sv}", "primary",
|
g_variant_builder_add (&properties, "{sv}", "primary",
|
||||||
g_variant_new_boolean (output->is_primary));
|
g_variant_new_boolean (output->is_primary));
|
||||||
g_variant_builder_add (&properties, "{sv}", "presentation",
|
g_variant_builder_add (&properties, "{sv}", "presentation",
|
||||||
|
@@ -1724,14 +1724,12 @@ get_default_focus_window (MetaStack *stack,
|
|||||||
* or top window in same group as not_this_one.
|
* or top window in same group as not_this_one.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MetaWindow *topmost_dock;
|
|
||||||
MetaWindow *transient_parent;
|
MetaWindow *transient_parent;
|
||||||
MetaWindow *topmost_in_group;
|
MetaWindow *topmost_in_group;
|
||||||
MetaWindow *topmost_overall;
|
MetaWindow *topmost_overall;
|
||||||
MetaGroup *not_this_one_group;
|
MetaGroup *not_this_one_group;
|
||||||
GList *link;
|
GList *link;
|
||||||
|
|
||||||
topmost_dock = NULL;
|
|
||||||
transient_parent = NULL;
|
transient_parent = NULL;
|
||||||
topmost_in_group = NULL;
|
topmost_in_group = NULL;
|
||||||
topmost_overall = NULL;
|
topmost_overall = NULL;
|
||||||
@@ -1757,10 +1755,6 @@ get_default_focus_window (MetaStack *stack,
|
|||||||
(workspace == NULL ||
|
(workspace == NULL ||
|
||||||
meta_window_located_on_workspace (window, workspace)))
|
meta_window_located_on_workspace (window, workspace)))
|
||||||
{
|
{
|
||||||
if (topmost_dock == NULL &&
|
|
||||||
window->type == META_WINDOW_DOCK)
|
|
||||||
topmost_dock = window;
|
|
||||||
|
|
||||||
if (not_this_one != NULL)
|
if (not_this_one != NULL)
|
||||||
{
|
{
|
||||||
if (transient_parent == NULL &&
|
if (transient_parent == NULL &&
|
||||||
@@ -1778,10 +1772,6 @@ get_default_focus_window (MetaStack *stack,
|
|||||||
topmost_in_group = window;
|
topmost_in_group = window;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note that DESKTOP windows can be topmost_overall so
|
|
||||||
* we prefer focusing desktop or other windows over
|
|
||||||
* focusing dock, even though docks are stacked higher.
|
|
||||||
*/
|
|
||||||
if (topmost_overall == NULL &&
|
if (topmost_overall == NULL &&
|
||||||
window->type != META_WINDOW_DOCK &&
|
window->type != META_WINDOW_DOCK &&
|
||||||
(!must_be_at_point ||
|
(!must_be_at_point ||
|
||||||
@@ -1803,7 +1793,7 @@ get_default_focus_window (MetaStack *stack,
|
|||||||
else if (topmost_overall)
|
else if (topmost_overall)
|
||||||
return topmost_overall;
|
return topmost_overall;
|
||||||
else
|
else
|
||||||
return topmost_dock;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaWindow*
|
MetaWindow*
|
||||||
|
@@ -44,6 +44,7 @@
|
|||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
#include "meta-wayland-types.h"
|
#include "meta-wayland-types.h"
|
||||||
|
|
||||||
typedef struct _MetaWindowQueue MetaWindowQueue;
|
typedef struct _MetaWindowQueue MetaWindowQueue;
|
||||||
@@ -642,8 +643,8 @@ void meta_window_update_sync_request_counter (MetaWindow *window,
|
|||||||
gint64 new_counter_value);
|
gint64 new_counter_value);
|
||||||
#endif /* HAVE_XSYNC */
|
#endif /* HAVE_XSYNC */
|
||||||
|
|
||||||
void meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
void meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||||
XIDeviceEvent *xev);
|
const ClutterEvent *event);
|
||||||
|
|
||||||
GList* meta_window_get_workspaces (MetaWindow *window);
|
GList* meta_window_get_workspaces (MetaWindow *window);
|
||||||
|
|
||||||
@@ -733,4 +734,9 @@ void meta_window_set_gtk_dbus_properties (MetaWindow *window,
|
|||||||
void meta_window_set_transient_for (MetaWindow *window,
|
void meta_window_set_transient_for (MetaWindow *window,
|
||||||
MetaWindow *parent);
|
MetaWindow *parent);
|
||||||
|
|
||||||
|
void meta_window_handle_enter (MetaWindow *window,
|
||||||
|
guint32 timestamp,
|
||||||
|
guint root_x,
|
||||||
|
guint root_y);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -63,6 +63,7 @@
|
|||||||
#include <X11/extensions/Xcomposite.h>
|
#include <X11/extensions/Xcomposite.h>
|
||||||
|
|
||||||
#include "meta-wayland-private.h"
|
#include "meta-wayland-private.h"
|
||||||
|
#include "meta/compositor-mutter.h"
|
||||||
|
|
||||||
/* Windows that unmaximize to a size bigger than that fraction of the workarea
|
/* Windows that unmaximize to a size bigger than that fraction of the workarea
|
||||||
* will be scaled down to that size (while maintaining aspect ratio).
|
* will be scaled down to that size (while maintaining aspect ratio).
|
||||||
@@ -2001,6 +2002,8 @@ meta_window_unmanage (MetaWindow *window,
|
|||||||
meta_window_ungrab_keys (window);
|
meta_window_ungrab_keys (window);
|
||||||
meta_display_ungrab_window_buttons (window->display, window->xwindow);
|
meta_display_ungrab_window_buttons (window->display, window->xwindow);
|
||||||
meta_display_ungrab_focus_window_button (window->display, window);
|
meta_display_ungrab_focus_window_button (window->display, window);
|
||||||
|
if (window->display->autoraise_window == window)
|
||||||
|
meta_display_remove_autoraise_callback (window->display);
|
||||||
|
|
||||||
if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||||
{
|
{
|
||||||
@@ -6836,8 +6839,7 @@ meta_window_property_notify (MetaWindow *window,
|
|||||||
void
|
void
|
||||||
meta_window_change_workspace_by_index (MetaWindow *window,
|
meta_window_change_workspace_by_index (MetaWindow *window,
|
||||||
gint space_index,
|
gint space_index,
|
||||||
gboolean append,
|
gboolean append)
|
||||||
guint32 timestamp)
|
|
||||||
{
|
{
|
||||||
MetaWorkspace *workspace;
|
MetaWorkspace *workspace;
|
||||||
MetaScreen *screen;
|
MetaScreen *screen;
|
||||||
@@ -6856,11 +6858,7 @@ meta_window_change_workspace_by_index (MetaWindow *window,
|
|||||||
meta_screen_get_workspace_by_index (screen, space_index);
|
meta_screen_get_workspace_by_index (screen, space_index);
|
||||||
|
|
||||||
if (!workspace && append)
|
if (!workspace && append)
|
||||||
{
|
workspace = meta_screen_append_new_workspace (screen, FALSE, CurrentTime);
|
||||||
if (timestamp == CurrentTime)
|
|
||||||
timestamp = meta_display_get_current_time_roundtrip (window->display);
|
|
||||||
workspace = meta_screen_append_new_workspace (screen, FALSE, timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (workspace)
|
if (workspace)
|
||||||
{
|
{
|
||||||
@@ -9906,96 +9904,20 @@ update_resize (MetaWindow *window,
|
|||||||
g_get_current_time (&window->display->grab_last_moveresize_time);
|
g_get_current_time (&window->display->grab_last_moveresize_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
Window window;
|
|
||||||
int count;
|
|
||||||
guint32 last_time;
|
|
||||||
} EventScannerData;
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
find_last_time_predicate (Display *display,
|
|
||||||
XEvent *ev,
|
|
||||||
XPointer arg)
|
|
||||||
{
|
|
||||||
EventScannerData *esd = (void*) arg;
|
|
||||||
XIEvent *xev;
|
|
||||||
|
|
||||||
if (ev->type != GenericEvent)
|
|
||||||
return False;
|
|
||||||
|
|
||||||
/* We are peeking into events not yet handled by GDK,
|
|
||||||
* Allocate cookie events here so we can handle XI2.
|
|
||||||
*
|
|
||||||
* GDK will handle later these events, and eventually
|
|
||||||
* free the cookie data itself.
|
|
||||||
*/
|
|
||||||
XGetEventData (display, &ev->xcookie);
|
|
||||||
xev = (XIEvent *) ev->xcookie.data;
|
|
||||||
|
|
||||||
if (xev->evtype != XI_Motion)
|
|
||||||
return False;
|
|
||||||
|
|
||||||
if (esd->window != ((XIDeviceEvent *) xev)->event)
|
|
||||||
return False;
|
|
||||||
|
|
||||||
esd->count += 1;
|
|
||||||
esd->last_time = xev->time;
|
|
||||||
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
check_use_this_motion_notify (MetaWindow *window,
|
check_use_this_motion_notify (MetaWindow *window,
|
||||||
XIDeviceEvent *xev)
|
const ClutterEvent *event)
|
||||||
{
|
{
|
||||||
EventScannerData esd;
|
/* XXX: Previously this code would walk through the X event queue
|
||||||
XEvent useless;
|
and filter out motion events that are followed by a later motion
|
||||||
|
event. There currently isn't any API to do the equivalent
|
||||||
/* This code is copied from Owen's GDK code. */
|
procedure with the Clutter event queue so this function does
|
||||||
|
nothing. Clutter does its own motion event squashing so it may be
|
||||||
if (window->display->grab_motion_notify_time != 0)
|
the case that this function isn't necessary. If it turns out that
|
||||||
{
|
we do need additional motion event squashing we could add some
|
||||||
/* == is really the right test, but I'm all for paranoia */
|
extra API to the Clutter event queue and implement this function
|
||||||
if (window->display->grab_motion_notify_time <=
|
properly. */
|
||||||
xev->time)
|
return TRUE;
|
||||||
{
|
|
||||||
meta_topic (META_DEBUG_RESIZING,
|
|
||||||
"Arrived at event with time %u (waiting for %u), using it\n",
|
|
||||||
(unsigned int)xev->time,
|
|
||||||
window->display->grab_motion_notify_time);
|
|
||||||
window->display->grab_motion_notify_time = 0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return FALSE; /* haven't reached the saved timestamp yet */
|
|
||||||
}
|
|
||||||
|
|
||||||
esd.window = xev->event;
|
|
||||||
esd.count = 0;
|
|
||||||
esd.last_time = 0;
|
|
||||||
|
|
||||||
/* "useless" isn't filled in because the predicate never returns True */
|
|
||||||
XCheckIfEvent (window->display->xdisplay,
|
|
||||||
&useless,
|
|
||||||
find_last_time_predicate,
|
|
||||||
(XPointer) &esd);
|
|
||||||
|
|
||||||
if (esd.count > 0)
|
|
||||||
meta_topic (META_DEBUG_RESIZING,
|
|
||||||
"Will skip %d motion events and use the event with time %u\n",
|
|
||||||
esd.count, (unsigned int) esd.last_time);
|
|
||||||
|
|
||||||
if (esd.last_time == 0)
|
|
||||||
return TRUE;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Save this timestamp, and ignore all motion notify
|
|
||||||
* until we get to the one with this stamp.
|
|
||||||
*/
|
|
||||||
window->display->grab_motion_notify_time = esd.last_time;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -10069,81 +9991,89 @@ meta_window_update_sync_request_counter (MetaWindow *window,
|
|||||||
#endif /* HAVE_XSYNC */
|
#endif /* HAVE_XSYNC */
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||||
XIDeviceEvent *xev)
|
const ClutterEvent *event)
|
||||||
{
|
{
|
||||||
switch (xev->evtype)
|
gboolean is_window_root = (event->any.stage != NULL &&
|
||||||
{
|
window &&
|
||||||
case XI_ButtonRelease:
|
window->screen &&
|
||||||
meta_display_check_threshold_reached (window->display,
|
CLUTTER_ACTOR (event->any.stage) ==
|
||||||
xev->root_x,
|
meta_get_stage_for_screen (window->screen));
|
||||||
xev->root_y);
|
|
||||||
/* If the user was snap moving then ignore the button release
|
|
||||||
* because they may have let go of shift before releasing the
|
|
||||||
* mouse button and they almost certainly do not want a
|
|
||||||
* non-snapped movement to occur from the button release.
|
|
||||||
*/
|
|
||||||
if (!window->display->grab_last_user_action_was_snap)
|
|
||||||
{
|
|
||||||
if (meta_grab_op_is_moving (window->display->grab_op))
|
|
||||||
{
|
|
||||||
if (window->tile_mode != META_TILE_NONE)
|
|
||||||
meta_window_tile (window);
|
|
||||||
else if (xev->root == window->screen->xroot)
|
|
||||||
update_move (window,
|
|
||||||
xev->mods.effective & ShiftMask,
|
|
||||||
xev->root_x,
|
|
||||||
xev->root_y);
|
|
||||||
}
|
|
||||||
else if (meta_grab_op_is_resizing (window->display->grab_op))
|
|
||||||
{
|
|
||||||
if (xev->root == window->screen->xroot)
|
|
||||||
update_resize (window,
|
|
||||||
xev->mods.effective & ShiftMask,
|
|
||||||
xev->root_x,
|
|
||||||
xev->root_y,
|
|
||||||
TRUE);
|
|
||||||
|
|
||||||
/* If a tiled window has been dragged free with a
|
switch (event->type)
|
||||||
* mouse resize without snapping back to the tiled
|
{
|
||||||
* state, it will end up with an inconsistent tile
|
case CLUTTER_BUTTON_RELEASE:
|
||||||
* mode on mouse release; cleaning the mode earlier
|
if (event->button.button == 1)
|
||||||
* would break the ability to snap back to the tiled
|
{
|
||||||
* state, so we wait until mouse release.
|
meta_display_check_threshold_reached (window->display,
|
||||||
*/
|
event->button.x,
|
||||||
update_tile_mode (window);
|
event->button.y);
|
||||||
|
/* If the user was snap moving then ignore the button
|
||||||
|
* release because they may have let go of shift before
|
||||||
|
* releasing the mouse button and they almost certainly do
|
||||||
|
* not want a non-snapped movement to occur from the button
|
||||||
|
* release.
|
||||||
|
*/
|
||||||
|
if (!window->display->grab_last_user_action_was_snap)
|
||||||
|
{
|
||||||
|
if (meta_grab_op_is_moving (window->display->grab_op))
|
||||||
|
{
|
||||||
|
if (window->tile_mode != META_TILE_NONE)
|
||||||
|
meta_window_tile (window);
|
||||||
|
else if (is_window_root)
|
||||||
|
update_move (window,
|
||||||
|
event->button.modifier_state & CLUTTER_SHIFT_MASK,
|
||||||
|
event->button.x,
|
||||||
|
event->button.y);
|
||||||
|
}
|
||||||
|
else if (meta_grab_op_is_resizing (window->display->grab_op))
|
||||||
|
{
|
||||||
|
if (is_window_root)
|
||||||
|
update_resize (window,
|
||||||
|
event->button.modifier_state & CLUTTER_SHIFT_MASK,
|
||||||
|
event->button.x,
|
||||||
|
event->button.y,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
/* If a tiled window has been dragged free with a
|
||||||
|
* mouse resize without snapping back to the tiled
|
||||||
|
* state, it will end up with an inconsistent tile
|
||||||
|
* mode on mouse release; cleaning the mode earlier
|
||||||
|
* would break the ability to snap back to the tiled
|
||||||
|
* state, so we wait until mouse release.
|
||||||
|
*/
|
||||||
|
update_tile_mode (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_display_end_grab_op (window->display, event->any.time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_display_end_grab_op (window->display, xev->time);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XI_Motion:
|
case CLUTTER_MOTION:
|
||||||
meta_display_check_threshold_reached (window->display,
|
meta_display_check_threshold_reached (window->display,
|
||||||
xev->root_x,
|
event->motion.x,
|
||||||
xev->root_y);
|
event->motion.y);
|
||||||
if (meta_grab_op_is_moving (window->display->grab_op))
|
if (meta_grab_op_is_moving (window->display->grab_op))
|
||||||
{
|
{
|
||||||
if (xev->root == window->screen->xroot)
|
if (is_window_root)
|
||||||
{
|
{
|
||||||
if (check_use_this_motion_notify (window,
|
if (check_use_this_motion_notify (window, event))
|
||||||
xev))
|
|
||||||
update_move (window,
|
update_move (window,
|
||||||
xev->mods.effective & ShiftMask,
|
event->button.modifier_state & CLUTTER_SHIFT_MASK,
|
||||||
xev->root_x,
|
event->motion.x,
|
||||||
xev->root_y);
|
event->motion.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (meta_grab_op_is_resizing (window->display->grab_op))
|
else if (meta_grab_op_is_resizing (window->display->grab_op))
|
||||||
{
|
{
|
||||||
if (xev->root == window->screen->xroot)
|
if (is_window_root)
|
||||||
{
|
{
|
||||||
if (check_use_this_motion_notify (window,
|
if (check_use_this_motion_notify (window, event))
|
||||||
xev))
|
|
||||||
update_resize (window,
|
update_resize (window,
|
||||||
xev->mods.effective & ShiftMask,
|
event->button.modifier_state & CLUTTER_SHIFT_MASK,
|
||||||
xev->root_x,
|
event->motion.x,
|
||||||
xev->root_y,
|
event->motion.y,
|
||||||
FALSE);
|
FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11739,3 +11669,185 @@ meta_window_set_transient_for (MetaWindow *window,
|
|||||||
if (meta_window_appears_focused (window) && window->transient_for != None)
|
if (meta_window_appears_focused (window) && window->transient_for != None)
|
||||||
meta_window_propagate_focus_appearance (window, TRUE);
|
meta_window_propagate_focus_appearance (window, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
reset_ignored_crossing_serials (MetaDisplay *display)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < N_IGNORED_CROSSING_SERIALS)
|
||||||
|
{
|
||||||
|
display->ignored_crossing_serials[i] = 0;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
display->ungrab_should_not_cause_focus_window = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MetaWindow *window;
|
||||||
|
int pointer_x;
|
||||||
|
int pointer_y;
|
||||||
|
} MetaFocusData;
|
||||||
|
|
||||||
|
static void
|
||||||
|
mouse_mode_focus (MetaWindow *window,
|
||||||
|
guint32 timestamp)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = window->display;
|
||||||
|
|
||||||
|
if (window->type != META_WINDOW_DESKTOP)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
|
"Focusing %s at time %u.\n", window->desc, timestamp);
|
||||||
|
|
||||||
|
meta_window_focus (window, timestamp);
|
||||||
|
|
||||||
|
if (meta_prefs_get_auto_raise ())
|
||||||
|
meta_display_queue_autoraise_callback (display, window);
|
||||||
|
else
|
||||||
|
meta_topic (META_DEBUG_FOCUS, "Auto raise is disabled\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* In mouse focus mode, we defocus when the mouse *enters*
|
||||||
|
* the DESKTOP window, instead of defocusing on LeaveNotify.
|
||||||
|
* This is because having the mouse enter override-redirect
|
||||||
|
* child windows unfortunately causes LeaveNotify events that
|
||||||
|
* we can't distinguish from the mouse actually leaving the
|
||||||
|
* toplevel window as we expect. But, since we filter out
|
||||||
|
* EnterNotify events on override-redirect windows, this
|
||||||
|
* alternative mechanism works great.
|
||||||
|
*/
|
||||||
|
if (meta_prefs_get_focus_mode() == G_DESKTOP_FOCUS_MODE_MOUSE &&
|
||||||
|
display->focus_window != NULL)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
|
"Unsetting focus from %s due to mouse entering "
|
||||||
|
"the DESKTOP window\n",
|
||||||
|
display->focus_window->desc);
|
||||||
|
meta_display_focus_the_no_focus_window (display,
|
||||||
|
window->screen,
|
||||||
|
timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
window_focus_on_pointer_rest_callback (gpointer data)
|
||||||
|
{
|
||||||
|
MetaFocusData *focus_data = data;
|
||||||
|
MetaWindow *window = focus_data->window;
|
||||||
|
MetaDisplay *display = window->display;
|
||||||
|
MetaScreen *screen = window->screen;
|
||||||
|
Window root, child;
|
||||||
|
double root_x, root_y, x, y;
|
||||||
|
guint32 timestamp;
|
||||||
|
XIButtonState buttons;
|
||||||
|
XIModifierState mods;
|
||||||
|
XIGroupState group;
|
||||||
|
|
||||||
|
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
XIQueryPointer (display->xdisplay,
|
||||||
|
META_VIRTUAL_CORE_POINTER_ID,
|
||||||
|
screen->xroot,
|
||||||
|
&root, &child,
|
||||||
|
&root_x, &root_y, &x, &y,
|
||||||
|
&buttons, &mods, &group);
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
free (buttons.mask);
|
||||||
|
|
||||||
|
if (root_x != focus_data->pointer_x ||
|
||||||
|
root_y != focus_data->pointer_y)
|
||||||
|
{
|
||||||
|
focus_data->pointer_x = root_x;
|
||||||
|
focus_data->pointer_y = root_y;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Explicitly check for the overlay window, as get_focus_window_at_point()
|
||||||
|
* may return windows that extend underneath the chrome (like
|
||||||
|
* override-redirect or DESKTOP windows)
|
||||||
|
*/
|
||||||
|
if (child == meta_get_overlay_window (screen))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
window =
|
||||||
|
meta_stack_get_default_focus_window_at_point (screen->stack,
|
||||||
|
screen->active_workspace,
|
||||||
|
None, root_x, root_y);
|
||||||
|
|
||||||
|
if (window == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
timestamp = meta_display_get_current_time_roundtrip (display);
|
||||||
|
mouse_mode_focus (window, timestamp);
|
||||||
|
|
||||||
|
out:
|
||||||
|
display->focus_timeout_id = 0;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The interval, in milliseconds, we use in focus-follows-mouse
|
||||||
|
* mode to check whether the pointer has stopped moving after a
|
||||||
|
* crossing event.
|
||||||
|
*/
|
||||||
|
#define FOCUS_TIMEOUT_DELAY 25
|
||||||
|
|
||||||
|
static void
|
||||||
|
queue_focus_callback (MetaDisplay *display,
|
||||||
|
MetaWindow *window,
|
||||||
|
int pointer_x,
|
||||||
|
int pointer_y)
|
||||||
|
{
|
||||||
|
MetaFocusData *focus_data;
|
||||||
|
|
||||||
|
focus_data = g_new (MetaFocusData, 1);
|
||||||
|
focus_data->window = window;
|
||||||
|
focus_data->pointer_x = pointer_x;
|
||||||
|
focus_data->pointer_y = pointer_y;
|
||||||
|
|
||||||
|
if (display->focus_timeout_id != 0)
|
||||||
|
g_source_remove (display->focus_timeout_id);
|
||||||
|
|
||||||
|
display->focus_timeout_id =
|
||||||
|
g_timeout_add_full (G_PRIORITY_DEFAULT,
|
||||||
|
FOCUS_TIMEOUT_DELAY,
|
||||||
|
window_focus_on_pointer_rest_callback,
|
||||||
|
focus_data,
|
||||||
|
g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_handle_enter (MetaWindow *window,
|
||||||
|
guint32 timestamp,
|
||||||
|
guint root_x,
|
||||||
|
guint root_y)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = window->display;
|
||||||
|
|
||||||
|
switch (meta_prefs_get_focus_mode ())
|
||||||
|
{
|
||||||
|
case G_DESKTOP_FOCUS_MODE_SLOPPY:
|
||||||
|
case G_DESKTOP_FOCUS_MODE_MOUSE:
|
||||||
|
display->mouse_mode = TRUE;
|
||||||
|
if (window->type != META_WINDOW_DOCK)
|
||||||
|
{
|
||||||
|
if (meta_prefs_get_focus_change_on_pointer_rest())
|
||||||
|
queue_focus_callback (display, window, root_x, root_y);
|
||||||
|
else
|
||||||
|
mouse_mode_focus (window, timestamp);
|
||||||
|
|
||||||
|
/* stop ignoring stuff */
|
||||||
|
reset_ignored_crossing_serials (display);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case G_DESKTOP_FOCUS_MODE_CLICK:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -536,6 +536,81 @@ meta_prop_get_utf8_list (MetaDisplay *display,
|
|||||||
return utf8_list_from_results (&results, str_p, n_str_p);
|
return utf8_list_from_results (&results, str_p, n_str_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this one freakishly returns g_malloc memory */
|
||||||
|
static gboolean
|
||||||
|
latin1_list_from_results (GetPropertyResults *results,
|
||||||
|
char ***str_p,
|
||||||
|
int *n_str_p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int n_strings;
|
||||||
|
char **retval;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
*str_p = NULL;
|
||||||
|
*n_str_p = 0;
|
||||||
|
|
||||||
|
if (!validate_or_free_results (results, 8, XA_STRING, FALSE))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* I'm not sure this is right, but I'm guessing the
|
||||||
|
* property is nul-separated
|
||||||
|
*/
|
||||||
|
i = 0;
|
||||||
|
n_strings = 0;
|
||||||
|
while (i < (int) results->n_items)
|
||||||
|
{
|
||||||
|
if (results->prop[i] == '\0')
|
||||||
|
++n_strings;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results->prop[results->n_items - 1] != '\0')
|
||||||
|
++n_strings;
|
||||||
|
|
||||||
|
/* we're guaranteed that results->prop has a nul on the end
|
||||||
|
* by XGetWindowProperty
|
||||||
|
*/
|
||||||
|
|
||||||
|
retval = g_new0 (char*, n_strings + 1);
|
||||||
|
|
||||||
|
p = (char *)results->prop;
|
||||||
|
i = 0;
|
||||||
|
while (i < n_strings)
|
||||||
|
{
|
||||||
|
retval[i] = g_strdup (p);
|
||||||
|
|
||||||
|
p = p + strlen (p) + 1;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
*str_p = retval;
|
||||||
|
*n_str_p = i;
|
||||||
|
|
||||||
|
meta_XFree (results->prop);
|
||||||
|
results->prop = NULL;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_prop_get_latin1_list (MetaDisplay *display,
|
||||||
|
Window xwindow,
|
||||||
|
Atom xatom,
|
||||||
|
char ***str_p,
|
||||||
|
int *n_str_p)
|
||||||
|
{
|
||||||
|
GetPropertyResults results;
|
||||||
|
|
||||||
|
*str_p = NULL;
|
||||||
|
|
||||||
|
if (!get_property (display, xwindow, xatom,
|
||||||
|
XA_STRING, &results))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return latin1_list_from_results (&results, str_p, n_str_p);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_prop_set_utf8_string_hint (MetaDisplay *display,
|
meta_prop_set_utf8_string_hint (MetaDisplay *display,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
|
@@ -102,6 +102,11 @@ gboolean meta_prop_get_utf8_list (MetaDisplay *display,
|
|||||||
Atom xatom,
|
Atom xatom,
|
||||||
char ***str_p,
|
char ***str_p,
|
||||||
int *n_str_p);
|
int *n_str_p);
|
||||||
|
gboolean meta_prop_get_latin1_list (MetaDisplay *display,
|
||||||
|
Window xwindow,
|
||||||
|
Atom xatom,
|
||||||
|
char ***str_p,
|
||||||
|
int *n_str_p);
|
||||||
void meta_prop_set_utf8_string_hint
|
void meta_prop_set_utf8_string_hint
|
||||||
(MetaDisplay *display,
|
(MetaDisplay *display,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
|
@@ -81,6 +81,7 @@ item(TIMESTAMP)
|
|||||||
item(VERSION)
|
item(VERSION)
|
||||||
item(ATOM_PAIR)
|
item(ATOM_PAIR)
|
||||||
item(BACKLIGHT)
|
item(BACKLIGHT)
|
||||||
|
item(_XKB_RULES_NAMES)
|
||||||
|
|
||||||
/* Oddities: These are used, and we need atoms for them,
|
/* Oddities: These are used, and we need atoms for them,
|
||||||
* but when we need all _NET_WM hints (i.e. when we're making
|
* but when we need all _NET_WM hints (i.e. when we're making
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/extensions/XInput.h>
|
#include <X11/extensions/XInput.h>
|
||||||
#include <X11/extensions/XInput2.h>
|
#include <X11/extensions/XInput2.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
@@ -35,13 +35,6 @@ gboolean meta_keybindings_set_custom_handler (const gchar *name,
|
|||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify free_data);
|
GDestroyNotify free_data);
|
||||||
|
|
||||||
void meta_keybindings_switch_window (MetaDisplay *display,
|
|
||||||
MetaScreen *screen,
|
|
||||||
MetaWindow *event_window,
|
|
||||||
XIDeviceEvent *event,
|
|
||||||
MetaKeyBinding *binding);
|
|
||||||
|
|
||||||
|
|
||||||
void meta_screen_ungrab_all_keys (MetaScreen *screen, guint32 timestamp);
|
void meta_screen_ungrab_all_keys (MetaScreen *screen, guint32 timestamp);
|
||||||
gboolean meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp);
|
gboolean meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -391,17 +391,17 @@ struct _MetaKeyCombo
|
|||||||
* @display: a #MetaDisplay
|
* @display: a #MetaDisplay
|
||||||
* @screen: a #MetaScreen
|
* @screen: a #MetaScreen
|
||||||
* @window: a #MetaWindow
|
* @window: a #MetaWindow
|
||||||
* @event: (type gpointer): a #XIDeviceEvent
|
* @event: a #ClutterKeyEvent
|
||||||
* @binding: a #MetaKeyBinding
|
* @binding: a #MetaKeyBinding
|
||||||
* @user_data: data passed to the function
|
* @user_data: data passed to the function
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display,
|
typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display,
|
||||||
MetaScreen *screen,
|
MetaScreen *screen,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
XIDeviceEvent *event,
|
ClutterKeyEvent *event,
|
||||||
MetaKeyBinding *binding,
|
MetaKeyBinding *binding,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
typedef struct _MetaKeyHandler MetaKeyHandler;
|
typedef struct _MetaKeyHandler MetaKeyHandler;
|
||||||
|
|
||||||
@@ -419,13 +419,13 @@ typedef struct
|
|||||||
*/
|
*/
|
||||||
GSList *bindings;
|
GSList *bindings;
|
||||||
|
|
||||||
/** for keybindings that can have shift or not like Alt+Tab */
|
/* for keybindings that can have shift or not like Alt+Tab */
|
||||||
gboolean add_shift:1;
|
gboolean add_shift:1;
|
||||||
|
|
||||||
/** for keybindings that apply only to a window */
|
/* for keybindings that apply only to a window */
|
||||||
gboolean per_window:1;
|
gboolean per_window:1;
|
||||||
|
|
||||||
/** for keybindings not added with meta_display_add_keybinding() */
|
/* for keybindings not added with meta_display_add_keybinding() */
|
||||||
gboolean builtin:1;
|
gboolean builtin:1;
|
||||||
} MetaKeyPref;
|
} MetaKeyPref;
|
||||||
|
|
||||||
|
@@ -150,8 +150,7 @@ void meta_window_unset_demands_attention (MetaWindow *window);
|
|||||||
const char* meta_window_get_startup_id (MetaWindow *window);
|
const char* meta_window_get_startup_id (MetaWindow *window);
|
||||||
void meta_window_change_workspace_by_index (MetaWindow *window,
|
void meta_window_change_workspace_by_index (MetaWindow *window,
|
||||||
gint space_index,
|
gint space_index,
|
||||||
gboolean append,
|
gboolean append);
|
||||||
guint32 timestamp);
|
|
||||||
void meta_window_change_workspace (MetaWindow *window,
|
void meta_window_change_workspace (MetaWindow *window,
|
||||||
MetaWorkspace *workspace);
|
MetaWorkspace *workspace);
|
||||||
GObject *meta_window_get_compositor_private (MetaWindow *window);
|
GObject *meta_window_get_compositor_private (MetaWindow *window);
|
||||||
|
@@ -106,11 +106,49 @@ create_anonymous_file (off_t size,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
meta_wayland_xkb_info_new_keymap (MetaWaylandXkbInfo *xkb_info)
|
inform_clients_of_new_keymap (MetaWaylandKeyboard *keyboard,
|
||||||
|
int flags)
|
||||||
{
|
{
|
||||||
|
MetaWaylandCompositor *compositor;
|
||||||
|
struct wl_client *xclient;
|
||||||
|
struct wl_resource *keyboard_resource;
|
||||||
|
|
||||||
|
compositor = meta_wayland_compositor_get_default ();
|
||||||
|
xclient = compositor->xwayland_client;
|
||||||
|
|
||||||
|
wl_resource_for_each (keyboard_resource, &keyboard->resource_list)
|
||||||
|
{
|
||||||
|
if ((flags & META_WAYLAND_KEYBOARD_SKIP_XCLIENTS) &&
|
||||||
|
wl_resource_get_client (keyboard_resource) == xclient)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wl_keyboard_send_keymap (keyboard_resource,
|
||||||
|
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
||||||
|
keyboard->xkb_info.keymap_fd,
|
||||||
|
keyboard->xkb_info.keymap_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
|
||||||
|
struct xkb_keymap *keymap,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
char *keymap_str;
|
char *keymap_str;
|
||||||
|
size_t previous_size;
|
||||||
|
|
||||||
|
if (keymap == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("Attempting to set null keymap (compilation probably failed)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xkb_info->keymap)
|
||||||
|
xkb_keymap_unref (xkb_info->keymap);
|
||||||
|
xkb_info->keymap = keymap;
|
||||||
|
|
||||||
xkb_info->shift_mod =
|
xkb_info->shift_mod =
|
||||||
xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_SHIFT);
|
xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_SHIFT);
|
||||||
@@ -129,21 +167,28 @@ meta_wayland_xkb_info_new_keymap (MetaWaylandXkbInfo *xkb_info)
|
|||||||
keymap_str = xkb_map_get_as_string (xkb_info->keymap);
|
keymap_str = xkb_map_get_as_string (xkb_info->keymap);
|
||||||
if (keymap_str == NULL)
|
if (keymap_str == NULL)
|
||||||
{
|
{
|
||||||
g_warning ("failed to get string version of keymap\n");
|
g_warning ("failed to get string version of keymap");
|
||||||
return FALSE;
|
return;
|
||||||
}
|
}
|
||||||
|
previous_size = xkb_info->keymap_size;
|
||||||
xkb_info->keymap_size = strlen (keymap_str) + 1;
|
xkb_info->keymap_size = strlen (keymap_str) + 1;
|
||||||
|
|
||||||
|
if (xkb_info->keymap_fd >= 0)
|
||||||
|
close (xkb_info->keymap_fd);
|
||||||
|
|
||||||
xkb_info->keymap_fd = create_anonymous_file (xkb_info->keymap_size, &error);
|
xkb_info->keymap_fd = create_anonymous_file (xkb_info->keymap_size, &error);
|
||||||
if (xkb_info->keymap_fd < 0)
|
if (xkb_info->keymap_fd < 0)
|
||||||
{
|
{
|
||||||
g_warning ("creating a keymap file for %lu bytes failed: %s\n",
|
g_warning ("creating a keymap file for %lu bytes failed: %s",
|
||||||
(unsigned long) xkb_info->keymap_size,
|
(unsigned long) xkb_info->keymap_size,
|
||||||
error->message);
|
error->message);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
goto err_keymap_str;
|
goto err_keymap_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xkb_info->keymap_area)
|
||||||
|
munmap (xkb_info->keymap_area, previous_size);
|
||||||
|
|
||||||
xkb_info->keymap_area = mmap (NULL, xkb_info->keymap_size,
|
xkb_info->keymap_area = mmap (NULL, xkb_info->keymap_size,
|
||||||
PROT_READ | PROT_WRITE,
|
PROT_READ | PROT_WRITE,
|
||||||
MAP_SHARED, xkb_info->keymap_fd, 0);
|
MAP_SHARED, xkb_info->keymap_fd, 0);
|
||||||
@@ -156,41 +201,24 @@ meta_wayland_xkb_info_new_keymap (MetaWaylandXkbInfo *xkb_info)
|
|||||||
strcpy (xkb_info->keymap_area, keymap_str);
|
strcpy (xkb_info->keymap_area, keymap_str);
|
||||||
free (keymap_str);
|
free (keymap_str);
|
||||||
|
|
||||||
return TRUE;
|
if (keyboard->is_evdev)
|
||||||
|
{
|
||||||
|
ClutterDeviceManager *manager;
|
||||||
|
|
||||||
|
manager = clutter_device_manager_get_default ();
|
||||||
|
clutter_evdev_set_keyboard_map (manager, xkb_info->keymap);
|
||||||
|
}
|
||||||
|
|
||||||
|
inform_clients_of_new_keymap (keyboard, flags);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
err_dev_zero:
|
err_dev_zero:
|
||||||
close (xkb_info->keymap_fd);
|
close (xkb_info->keymap_fd);
|
||||||
xkb_info->keymap_fd = -1;
|
xkb_info->keymap_fd = -1;
|
||||||
err_keymap_str:
|
err_keymap_str:
|
||||||
free (keymap_str);
|
free (keymap_str);
|
||||||
return FALSE;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
meta_wayland_keyboard_build_global_keymap (struct xkb_context *xkb_context,
|
|
||||||
struct xkb_rule_names *xkb_names,
|
|
||||||
MetaWaylandXkbInfo *xkb_info)
|
|
||||||
{
|
|
||||||
xkb_info->keymap = xkb_map_new_from_names (xkb_context,
|
|
||||||
xkb_names,
|
|
||||||
0 /* flags */);
|
|
||||||
if (xkb_info->keymap == NULL)
|
|
||||||
{
|
|
||||||
g_warning ("failed to compile global XKB keymap\n"
|
|
||||||
" tried rules %s, model %s, layout %s, variant %s, "
|
|
||||||
"options %s\n",
|
|
||||||
xkb_names->rules,
|
|
||||||
xkb_names->model,
|
|
||||||
xkb_names->layout,
|
|
||||||
xkb_names->variant,
|
|
||||||
xkb_names->options);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!meta_wayland_xkb_info_new_keymap (xkb_info))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -306,9 +334,8 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
|||||||
struct wl_display *display,
|
struct wl_display *display,
|
||||||
gboolean is_evdev)
|
gboolean is_evdev)
|
||||||
{
|
{
|
||||||
ClutterDeviceManager *manager;
|
|
||||||
|
|
||||||
memset (keyboard, 0, sizeof *keyboard);
|
memset (keyboard, 0, sizeof *keyboard);
|
||||||
|
keyboard->xkb_info.keymap_fd = -1;
|
||||||
|
|
||||||
wl_list_init (&keyboard->resource_list);
|
wl_list_init (&keyboard->resource_list);
|
||||||
wl_array_init (&keyboard->keys);
|
wl_array_init (&keyboard->keys);
|
||||||
@@ -320,18 +347,15 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
|||||||
keyboard->display = display;
|
keyboard->display = display;
|
||||||
|
|
||||||
keyboard->xkb_context = xkb_context_new (0 /* flags */);
|
keyboard->xkb_context = xkb_context_new (0 /* flags */);
|
||||||
|
|
||||||
meta_wayland_keyboard_build_global_keymap (keyboard->xkb_context,
|
|
||||||
&keyboard->xkb_names,
|
|
||||||
&keyboard->xkb_info);
|
|
||||||
|
|
||||||
keyboard->is_evdev = is_evdev;
|
keyboard->is_evdev = is_evdev;
|
||||||
if (is_evdev)
|
|
||||||
{
|
|
||||||
manager = clutter_device_manager_get_default ();
|
|
||||||
|
|
||||||
clutter_evdev_set_keyboard_map (manager, keyboard->xkb_info.keymap);
|
/* Compute a default until gnome-settings-daemon starts and sets
|
||||||
}
|
the appropriate values
|
||||||
|
*/
|
||||||
|
meta_wayland_keyboard_set_keymap_names (keyboard,
|
||||||
|
"evdev",
|
||||||
|
"pc105",
|
||||||
|
"us", "", "", 0);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -559,12 +583,6 @@ meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard)
|
|||||||
void
|
void
|
||||||
meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard)
|
meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
g_free ((char *) keyboard->xkb_names.rules);
|
|
||||||
g_free ((char *) keyboard->xkb_names.model);
|
|
||||||
g_free ((char *) keyboard->xkb_names.layout);
|
|
||||||
g_free ((char *) keyboard->xkb_names.variant);
|
|
||||||
g_free ((char *) keyboard->xkb_names.options);
|
|
||||||
|
|
||||||
meta_wayland_xkb_info_destroy (&keyboard->xkb_info);
|
meta_wayland_xkb_info_destroy (&keyboard->xkb_info);
|
||||||
xkb_context_unref (keyboard->xkb_context);
|
xkb_context_unref (keyboard->xkb_context);
|
||||||
|
|
||||||
@@ -652,3 +670,28 @@ meta_wayland_keyboard_end_modal (MetaWaylandKeyboard *keyboard,
|
|||||||
|
|
||||||
meta_verbose ("Released modal keyboard grab, timestamp %d\n", timestamp);
|
meta_verbose ("Released modal keyboard grab, timestamp %d\n", timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_keyboard_set_keymap_names (MetaWaylandKeyboard *keyboard,
|
||||||
|
const char *rules,
|
||||||
|
const char *model,
|
||||||
|
const char *layout,
|
||||||
|
const char *variant,
|
||||||
|
const char *options,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
struct xkb_rule_names xkb_names;
|
||||||
|
|
||||||
|
xkb_names.rules = rules;
|
||||||
|
xkb_names.model = model;
|
||||||
|
xkb_names.layout = layout;
|
||||||
|
xkb_names.variant = variant;
|
||||||
|
xkb_names.options = options;
|
||||||
|
|
||||||
|
meta_wayland_keyboard_take_keymap (keyboard,
|
||||||
|
xkb_keymap_new_from_names (keyboard->xkb_context,
|
||||||
|
&xkb_names,
|
||||||
|
0 /* flags */),
|
||||||
|
flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -112,7 +112,6 @@ struct _MetaWaylandKeyboard
|
|||||||
struct xkb_context *xkb_context;
|
struct xkb_context *xkb_context;
|
||||||
gboolean is_evdev;
|
gboolean is_evdev;
|
||||||
MetaWaylandXkbInfo xkb_info;
|
MetaWaylandXkbInfo xkb_info;
|
||||||
struct xkb_rule_names xkb_names;
|
|
||||||
|
|
||||||
MetaWaylandKeyboardGrab input_method_grab;
|
MetaWaylandKeyboardGrab input_method_grab;
|
||||||
struct wl_resource *input_method_resource;
|
struct wl_resource *input_method_resource;
|
||||||
@@ -123,6 +122,18 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
|||||||
struct wl_display *display,
|
struct wl_display *display,
|
||||||
gboolean is_evdev);
|
gboolean is_evdev);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
META_WAYLAND_KEYBOARD_SKIP_XCLIENTS = 1,
|
||||||
|
} MetaWaylandKeyboardSetKeymapFlags;
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_keyboard_set_keymap_names (MetaWaylandKeyboard *keyboard,
|
||||||
|
const char *rules,
|
||||||
|
const char *model,
|
||||||
|
const char *layout,
|
||||||
|
const char *variant,
|
||||||
|
const char *options,
|
||||||
|
int flags);
|
||||||
gboolean
|
gboolean
|
||||||
meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
|
meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
|
||||||
const ClutterKeyEvent *event);
|
const ClutterKeyEvent *event);
|
||||||
|
@@ -352,6 +352,11 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
meta_wayland_pointer_get_relative_coordinates (pointer, surface, &sx, &sy);
|
meta_wayland_pointer_get_relative_coordinates (pointer, surface, &sx, &sy);
|
||||||
|
meta_window_handle_enter (surface->window,
|
||||||
|
/* XXX -- can we reliably get a timestamp for setting focus? */
|
||||||
|
clutter_get_current_event_time (),
|
||||||
|
wl_fixed_to_int (pointer->x),
|
||||||
|
wl_fixed_to_int (pointer->y));
|
||||||
wl_pointer_send_enter (resource, serial, surface->resource, sx, sy);
|
wl_pointer_send_enter (resource, serial, surface->resource, sx, sy);
|
||||||
wl_resource_add_destroy_listener (resource, &pointer->focus_listener);
|
wl_resource_add_destroy_listener (resource, &pointer->focus_listener);
|
||||||
pointer->focus_serial = serial;
|
pointer->focus_serial = serial;
|
||||||
@@ -385,32 +390,6 @@ meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer)
|
|||||||
interface->focus (pointer->grab, pointer->current, NULL);
|
interface->focus (pointer->grab, pointer->current, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
current_surface_destroy (struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
MetaWaylandPointer *pointer =
|
|
||||||
wl_container_of (listener, pointer, current_listener);
|
|
||||||
|
|
||||||
pointer->current = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_wayland_pointer_set_current (MetaWaylandPointer *pointer,
|
|
||||||
MetaWaylandSurface *surface)
|
|
||||||
{
|
|
||||||
if (pointer->current)
|
|
||||||
wl_list_remove (&pointer->current_listener.link);
|
|
||||||
|
|
||||||
pointer->current = surface;
|
|
||||||
|
|
||||||
if (!surface)
|
|
||||||
return;
|
|
||||||
|
|
||||||
wl_resource_add_destroy_listener (surface->resource,
|
|
||||||
&pointer->current_listener);
|
|
||||||
pointer->current_listener.notify = current_surface_destroy;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
modal_focus (MetaWaylandPointerGrab *grab,
|
modal_focus (MetaWaylandPointerGrab *grab,
|
||||||
MetaWaylandSurface *surface,
|
MetaWaylandSurface *surface,
|
||||||
|
@@ -62,8 +62,6 @@ struct _MetaWaylandPointer
|
|||||||
|
|
||||||
wl_fixed_t x, y; /* TODO: remove, use ClutterInputDevice instead */
|
wl_fixed_t x, y; /* TODO: remove, use ClutterInputDevice instead */
|
||||||
MetaWaylandSurface *current;
|
MetaWaylandSurface *current;
|
||||||
struct wl_listener current_listener;
|
|
||||||
wl_fixed_t current_x, current_y;
|
|
||||||
|
|
||||||
guint32 button_count;
|
guint32 button_count;
|
||||||
};
|
};
|
||||||
@@ -97,10 +95,6 @@ gboolean
|
|||||||
meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
|
meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
|
||||||
MetaWaylandSurface *popup);
|
MetaWaylandSurface *popup);
|
||||||
|
|
||||||
void
|
|
||||||
meta_wayland_pointer_set_current (MetaWaylandPointer *pointer,
|
|
||||||
MetaWaylandSurface *surface);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer,
|
meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer,
|
||||||
MetaWaylandSurface *surface,
|
MetaWaylandSurface *surface,
|
||||||
|
@@ -83,14 +83,6 @@ struct _MetaWaylandCompositor
|
|||||||
int drm_fd;
|
int drm_fd;
|
||||||
|
|
||||||
MetaWaylandSeat *seat;
|
MetaWaylandSeat *seat;
|
||||||
|
|
||||||
/* This surface is only used to keep drag of the implicit grab when
|
|
||||||
synthesizing XEvents for Mutter */
|
|
||||||
MetaWaylandSurface *implicit_grab_surface;
|
|
||||||
/* Button that was pressed to initiate an implicit grab. The
|
|
||||||
implicit grab will only be released when this button is
|
|
||||||
released */
|
|
||||||
guint32 implicit_grab_button;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void meta_wayland_init (void);
|
void meta_wayland_init (void);
|
||||||
@@ -104,6 +96,8 @@ void meta_wayland_compositor_repick (MetaWaylandComp
|
|||||||
|
|
||||||
void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor,
|
void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor,
|
||||||
MetaWindow *window);
|
MetaWindow *window);
|
||||||
|
gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor,
|
||||||
|
const ClutterEvent *event);
|
||||||
|
|
||||||
MetaLauncher *meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor);
|
MetaLauncher *meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor);
|
||||||
gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor);
|
gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor);
|
||||||
|
@@ -280,31 +280,9 @@ handle_button_event (MetaWaylandSeat *seat,
|
|||||||
const ClutterEvent *event)
|
const ClutterEvent *event)
|
||||||
{
|
{
|
||||||
MetaWaylandPointer *pointer = &seat->pointer;
|
MetaWaylandPointer *pointer = &seat->pointer;
|
||||||
gboolean state = event->type == CLUTTER_BUTTON_PRESS;
|
|
||||||
uint32_t button;
|
|
||||||
MetaWaylandSurface *surface;
|
|
||||||
|
|
||||||
notify_motion (seat, event);
|
notify_motion (seat, event);
|
||||||
|
|
||||||
if (state && pointer->button_count == 1)
|
|
||||||
{
|
|
||||||
button = clutter_event_get_button (event);
|
|
||||||
pointer->grab_button = button;
|
|
||||||
pointer->grab_time = clutter_event_get_time (event);
|
|
||||||
pointer->grab_x = pointer->x;
|
|
||||||
pointer->grab_y = pointer->y;
|
|
||||||
|
|
||||||
/* FIXME: synth a XI2 event and handle in display.c */
|
|
||||||
surface = pointer->current;
|
|
||||||
if (button == CLUTTER_BUTTON_PRIMARY &&
|
|
||||||
surface &&
|
|
||||||
surface->window &&
|
|
||||||
surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
|
||||||
{
|
|
||||||
meta_window_raise (surface->window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pointer->grab->interface->button (pointer->grab, event);
|
pointer->grab->interface->button (pointer->grab, event);
|
||||||
|
|
||||||
if (pointer->button_count == 1)
|
if (pointer->button_count == 1)
|
||||||
@@ -381,6 +359,19 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
|
|||||||
{
|
{
|
||||||
seat->pointer.button_count = count_buttons (event);
|
seat->pointer.button_count = count_buttons (event);
|
||||||
|
|
||||||
|
if (seat->cursor_tracker)
|
||||||
|
{
|
||||||
|
meta_cursor_tracker_update_position (seat->cursor_tracker,
|
||||||
|
wl_fixed_to_int (seat->pointer.x),
|
||||||
|
wl_fixed_to_int (seat->pointer.y));
|
||||||
|
|
||||||
|
if (seat->pointer.current == NULL)
|
||||||
|
meta_cursor_tracker_revert_root (seat->cursor_tracker);
|
||||||
|
|
||||||
|
meta_cursor_tracker_queue_redraw (seat->cursor_tracker,
|
||||||
|
CLUTTER_ACTOR (event->any.stage));
|
||||||
|
}
|
||||||
|
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
case CLUTTER_MOTION:
|
case CLUTTER_MOTION:
|
||||||
@@ -408,20 +399,6 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
update_pointer_position_for_actor (MetaWaylandPointer *pointer,
|
|
||||||
ClutterActor *actor)
|
|
||||||
{
|
|
||||||
float ax, ay;
|
|
||||||
|
|
||||||
clutter_actor_transform_stage_point (actor,
|
|
||||||
wl_fixed_to_double (pointer->x),
|
|
||||||
wl_fixed_to_double (pointer->y),
|
|
||||||
&ax, &ay);
|
|
||||||
pointer->current_x = wl_fixed_from_double (ax);
|
|
||||||
pointer->current_y = wl_fixed_from_double (ay);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The actor argument can be NULL in which case a Clutter pick will be
|
/* The actor argument can be NULL in which case a Clutter pick will be
|
||||||
performed to determine the right actor. An actor should only be
|
performed to determine the right actor. An actor should only be
|
||||||
passed if the repick is being performed due to an event in which
|
passed if the repick is being performed due to an event in which
|
||||||
@@ -458,16 +435,12 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat,
|
|||||||
MetaWindow *window =
|
MetaWindow *window =
|
||||||
meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor));
|
meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor));
|
||||||
|
|
||||||
update_pointer_position_for_actor (pointer, actor);
|
|
||||||
|
|
||||||
surface = window->surface;
|
surface = window->surface;
|
||||||
}
|
}
|
||||||
else if (META_IS_SHAPED_TEXTURE (actor))
|
else if (META_IS_SHAPED_TEXTURE (actor))
|
||||||
{
|
{
|
||||||
MetaShapedTexture *shaped_texture = META_SHAPED_TEXTURE (actor);
|
MetaShapedTexture *shaped_texture = META_SHAPED_TEXTURE (actor);
|
||||||
|
|
||||||
update_pointer_position_for_actor (pointer, actor);
|
|
||||||
|
|
||||||
surface = meta_shaped_texture_get_wayland_surface (shaped_texture);
|
surface = meta_shaped_texture_get_wayland_surface (shaped_texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -409,9 +409,6 @@ meta_wayland_surface_free (MetaWaylandSurface *surface)
|
|||||||
g_assert (surface != compositor->seat->pointer.focus);
|
g_assert (surface != compositor->seat->pointer.focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compositor->implicit_grab_surface == surface)
|
|
||||||
compositor->implicit_grab_surface = compositor->seat->pointer.current;
|
|
||||||
|
|
||||||
if (surface->resource)
|
if (surface->resource)
|
||||||
wl_resource_set_user_data (surface->resource, NULL);
|
wl_resource_set_user_data (surface->resource, NULL);
|
||||||
g_slice_free (MetaWaylandSurface, surface);
|
g_slice_free (MetaWaylandSurface, surface);
|
||||||
|
@@ -533,119 +533,6 @@ stage_destroy_cb (void)
|
|||||||
meta_quit (META_EXIT_SUCCESS);
|
meta_quit (META_EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define N_BUTTONS 5
|
|
||||||
|
|
||||||
static void
|
|
||||||
synthesize_motion_event (MetaWaylandCompositor *compositor,
|
|
||||||
const ClutterEvent *event)
|
|
||||||
{
|
|
||||||
/* We want to synthesize X events for mouse motion events so that we
|
|
||||||
don't have to rely on the X server's window position being
|
|
||||||
synched with the surface position. See the comment in
|
|
||||||
event_callback() in display.c */
|
|
||||||
MetaWaylandSeat *seat = compositor->seat;
|
|
||||||
MetaWaylandPointer *pointer = &seat->pointer;
|
|
||||||
MetaWaylandSurface *surface;
|
|
||||||
XGenericEventCookie generic_event;
|
|
||||||
XIDeviceEvent device_event;
|
|
||||||
unsigned char button_mask[(N_BUTTONS + 7) / 8] = { 0 };
|
|
||||||
MetaDisplay *display = meta_get_display ();
|
|
||||||
ClutterModifierType button_state;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
generic_event.type = GenericEvent;
|
|
||||||
generic_event.serial = 0;
|
|
||||||
generic_event.send_event = False;
|
|
||||||
generic_event.display = display->xdisplay;
|
|
||||||
generic_event.extension = display->xinput_opcode;
|
|
||||||
generic_event.evtype = XI_Motion;
|
|
||||||
/* Mutter assumes the data for the event is already retrieved by GDK
|
|
||||||
* so we don't need the cookie */
|
|
||||||
generic_event.cookie = 0;
|
|
||||||
generic_event.data = &device_event;
|
|
||||||
|
|
||||||
memcpy (&device_event, &generic_event, sizeof (XGenericEvent));
|
|
||||||
|
|
||||||
device_event.time = clutter_event_get_time (event);
|
|
||||||
device_event.deviceid = clutter_event_get_device_id (event);
|
|
||||||
device_event.sourceid = 0; /* not used, not sure what this should be */
|
|
||||||
device_event.detail = 0;
|
|
||||||
device_event.root = DefaultRootWindow (display->xdisplay);
|
|
||||||
device_event.flags = 0 /* not used for motion events */;
|
|
||||||
|
|
||||||
if (compositor->implicit_grab_surface)
|
|
||||||
surface = compositor->implicit_grab_surface;
|
|
||||||
else
|
|
||||||
surface = pointer->current;
|
|
||||||
|
|
||||||
if (surface == pointer->current)
|
|
||||||
{
|
|
||||||
device_event.event_x = wl_fixed_to_int (pointer->current_x);
|
|
||||||
device_event.event_y = wl_fixed_to_int (pointer->current_y);
|
|
||||||
}
|
|
||||||
else if (surface && surface->window)
|
|
||||||
{
|
|
||||||
ClutterActor *window_actor =
|
|
||||||
CLUTTER_ACTOR (meta_window_get_compositor_private (surface->window));
|
|
||||||
|
|
||||||
if (window_actor)
|
|
||||||
{
|
|
||||||
float ax, ay;
|
|
||||||
|
|
||||||
clutter_actor_transform_stage_point (window_actor,
|
|
||||||
wl_fixed_to_double (pointer->x),
|
|
||||||
wl_fixed_to_double (pointer->y),
|
|
||||||
&ax, &ay);
|
|
||||||
|
|
||||||
device_event.event_x = ax;
|
|
||||||
device_event.event_y = ay;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
device_event.event_x = wl_fixed_to_double (pointer->x);
|
|
||||||
device_event.event_y = wl_fixed_to_double (pointer->y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
device_event.event_x = wl_fixed_to_double (pointer->x);
|
|
||||||
device_event.event_y = wl_fixed_to_double (pointer->y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (surface && surface->window != NULL)
|
|
||||||
device_event.event = surface->window->xwindow;
|
|
||||||
else
|
|
||||||
device_event.event = device_event.root;
|
|
||||||
|
|
||||||
/* Mutter doesn't really know about the sub-windows. This assumes it
|
|
||||||
doesn't care either */
|
|
||||||
device_event.child = device_event.event;
|
|
||||||
device_event.root_x = wl_fixed_to_double (pointer->x);
|
|
||||||
device_event.root_y = wl_fixed_to_double (pointer->y);
|
|
||||||
|
|
||||||
clutter_event_get_state_full (event,
|
|
||||||
&button_state,
|
|
||||||
(ClutterModifierType*)&device_event.mods.base,
|
|
||||||
(ClutterModifierType*)&device_event.mods.latched,
|
|
||||||
(ClutterModifierType*)&device_event.mods.locked,
|
|
||||||
(ClutterModifierType*)&device_event.mods.effective);
|
|
||||||
device_event.mods.effective &= ~button_state;
|
|
||||||
memset (&device_event.group, 0, sizeof (device_event.group));
|
|
||||||
device_event.group.effective = (device_event.mods.effective >> 13) & 0x3;
|
|
||||||
|
|
||||||
for (i = 0; i < N_BUTTONS; i++)
|
|
||||||
if ((button_state & (CLUTTER_BUTTON1_MASK << i)))
|
|
||||||
XISetMask (button_mask, i + 1);
|
|
||||||
device_event.buttons.mask_len = N_BUTTONS + 1;
|
|
||||||
device_event.buttons.mask = button_mask;
|
|
||||||
|
|
||||||
device_event.valuators.mask_len = 0;
|
|
||||||
device_event.valuators.mask = NULL;
|
|
||||||
device_event.valuators.values = NULL;
|
|
||||||
|
|
||||||
meta_display_handle_event (display, (XEvent *) &generic_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reset_idletimes (const ClutterEvent *event)
|
reset_idletimes (const ClutterEvent *event)
|
||||||
{
|
{
|
||||||
@@ -671,132 +558,13 @@ reset_idletimes (const ClutterEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
gboolean
|
||||||
event_cb (ClutterActor *stage,
|
meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor,
|
||||||
const ClutterEvent *event,
|
const ClutterEvent *event)
|
||||||
MetaWaylandCompositor *compositor)
|
|
||||||
{
|
{
|
||||||
MetaWaylandSeat *seat = compositor->seat;
|
|
||||||
MetaWaylandPointer *pointer = &seat->pointer;
|
|
||||||
MetaWaylandSurface *surface;
|
|
||||||
MetaDisplay *display;
|
|
||||||
|
|
||||||
reset_idletimes (event);
|
reset_idletimes (event);
|
||||||
|
|
||||||
if (meta_wayland_seat_handle_event (compositor->seat, event))
|
return meta_wayland_seat_handle_event (compositor->seat, event);
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* HACK: for now, the surfaces from Wayland clients aren't
|
|
||||||
integrated into Mutter's event handling and Mutter won't give them
|
|
||||||
focus on mouse clicks. As a hack to work around this we can just
|
|
||||||
give them input focus on mouse clicks so we can at least test the
|
|
||||||
keyboard support */
|
|
||||||
if (event->type == CLUTTER_BUTTON_PRESS)
|
|
||||||
{
|
|
||||||
surface = pointer->current;
|
|
||||||
|
|
||||||
if (surface && surface->window &&
|
|
||||||
surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
|
||||||
{
|
|
||||||
MetaDisplay *display = meta_get_display ();
|
|
||||||
guint32 timestamp = meta_display_get_current_time_roundtrip (display);
|
|
||||||
|
|
||||||
meta_window_focus (surface->window, timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seat->cursor_tracker)
|
|
||||||
{
|
|
||||||
meta_cursor_tracker_update_position (seat->cursor_tracker,
|
|
||||||
wl_fixed_to_int (pointer->x),
|
|
||||||
wl_fixed_to_int (pointer->y));
|
|
||||||
|
|
||||||
if (pointer->current == NULL)
|
|
||||||
meta_cursor_tracker_revert_root (seat->cursor_tracker);
|
|
||||||
|
|
||||||
meta_cursor_tracker_queue_redraw (seat->cursor_tracker, stage);
|
|
||||||
}
|
|
||||||
|
|
||||||
display = meta_get_display ();
|
|
||||||
if (!display)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
switch (event->type)
|
|
||||||
{
|
|
||||||
case CLUTTER_BUTTON_PRESS:
|
|
||||||
if (compositor->implicit_grab_surface == NULL)
|
|
||||||
{
|
|
||||||
compositor->implicit_grab_button = event->button.button;
|
|
||||||
compositor->implicit_grab_surface = pointer->current;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
case CLUTTER_BUTTON_RELEASE:
|
|
||||||
if (event->type == CLUTTER_BUTTON_RELEASE &&
|
|
||||||
compositor->implicit_grab_surface &&
|
|
||||||
event->button.button == compositor->implicit_grab_button)
|
|
||||||
compositor->implicit_grab_surface = NULL;
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
case CLUTTER_MOTION:
|
|
||||||
synthesize_motion_event (compositor, event);
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
event_emission_hook_cb (GSignalInvocationHint *ihint,
|
|
||||||
guint n_param_values,
|
|
||||||
const GValue *param_values,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
MetaWaylandCompositor *compositor = data;
|
|
||||||
ClutterActor *actor;
|
|
||||||
ClutterEvent *event;
|
|
||||||
|
|
||||||
g_return_val_if_fail (n_param_values == 2, FALSE);
|
|
||||||
|
|
||||||
actor = g_value_get_object (param_values + 0);
|
|
||||||
event = g_value_get_boxed (param_values + 1);
|
|
||||||
|
|
||||||
if (actor == NULL)
|
|
||||||
return TRUE /* stay connected */;
|
|
||||||
|
|
||||||
/* If this event belongs to the corresponding grab for this event
|
|
||||||
* type then the captured-event signal won't be emitted so we have
|
|
||||||
* to manually forward it on */
|
|
||||||
|
|
||||||
switch (event->type)
|
|
||||||
{
|
|
||||||
/* Pointer events */
|
|
||||||
case CLUTTER_MOTION:
|
|
||||||
case CLUTTER_ENTER:
|
|
||||||
case CLUTTER_LEAVE:
|
|
||||||
case CLUTTER_BUTTON_PRESS:
|
|
||||||
case CLUTTER_BUTTON_RELEASE:
|
|
||||||
case CLUTTER_SCROLL:
|
|
||||||
if (actor == clutter_get_pointer_grab ())
|
|
||||||
event_cb (clutter_actor_get_stage (actor),
|
|
||||||
event,
|
|
||||||
compositor);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Keyboard events */
|
|
||||||
case CLUTTER_KEY_PRESS:
|
|
||||||
case CLUTTER_KEY_RELEASE:
|
|
||||||
if (actor == clutter_get_keyboard_grab ())
|
|
||||||
event_cb (clutter_actor_get_stage (actor),
|
|
||||||
event,
|
|
||||||
compositor);
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE /* stay connected */;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -839,7 +607,6 @@ void
|
|||||||
meta_wayland_init (void)
|
meta_wayland_init (void)
|
||||||
{
|
{
|
||||||
MetaWaylandCompositor *compositor = &_meta_wayland_compositor;
|
MetaWaylandCompositor *compositor = &_meta_wayland_compositor;
|
||||||
guint event_signal;
|
|
||||||
MetaMonitorManager *monitors;
|
MetaMonitorManager *monitors;
|
||||||
ClutterBackend *backend;
|
ClutterBackend *backend;
|
||||||
CoglContext *cogl_context;
|
CoglContext *cogl_context;
|
||||||
@@ -928,21 +695,6 @@ meta_wayland_init (void)
|
|||||||
compositor->seat = meta_wayland_seat_new (compositor->wayland_display,
|
compositor->seat = meta_wayland_seat_new (compositor->wayland_display,
|
||||||
compositor->drm_fd >= 0);
|
compositor->drm_fd >= 0);
|
||||||
|
|
||||||
g_signal_connect (compositor->stage,
|
|
||||||
"captured-event",
|
|
||||||
G_CALLBACK (event_cb),
|
|
||||||
compositor);
|
|
||||||
/* If something sets a grab on an actor then the captured event
|
|
||||||
* signal won't get emitted but we still want to see these events so
|
|
||||||
* we can update the cursor position. To make sure we see all events
|
|
||||||
* we also install an emission hook on the event signal */
|
|
||||||
event_signal = g_signal_lookup ("event", CLUTTER_TYPE_STAGE);
|
|
||||||
g_signal_add_emission_hook (event_signal,
|
|
||||||
0 /* detail */,
|
|
||||||
event_emission_hook_cb,
|
|
||||||
compositor, /* hook_data */
|
|
||||||
NULL /* data_destroy */);
|
|
||||||
|
|
||||||
meta_wayland_init_shell (compositor);
|
meta_wayland_init_shell (compositor);
|
||||||
|
|
||||||
clutter_actor_show (compositor->stage);
|
clutter_actor_show (compositor->stage);
|
||||||
|
Reference in New Issue
Block a user