Allow setting input region before output window is created
If mutter_plugin_set_stage_input_region() and related methods are called before the output window is available, save the set input region and apply it to the output window later on. compository-mutter.[ch]: Add mutter_set_stage_input_region() and mutter_empty_stage_input_region(), move the input region handling here and implement the delayed shape setting described above. mutter-plugin.c: Implement shape setting in terms of the new methods. http://bugzilla.gnome.org/show_bug.cgi?id=580042
This commit is contained in:
parent
76a3f9d402
commit
7a7632fa98
@ -148,6 +148,9 @@ typedef struct _MetaCompScreen
|
||||
Window output;
|
||||
GSList *dock_windows;
|
||||
|
||||
/* Before we create the output window */
|
||||
XserverRegion pending_input_region;
|
||||
|
||||
gint switch_workspace_in_progress;
|
||||
|
||||
MutterPluginManager *plugin_mgr;
|
||||
@ -1827,6 +1830,45 @@ mutter_get_windows (MetaScreen *screen)
|
||||
return info->windows;
|
||||
}
|
||||
|
||||
void
|
||||
mutter_set_stage_input_region (MetaScreen *screen,
|
||||
XserverRegion region)
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
|
||||
if (info->stage && info->output)
|
||||
{
|
||||
Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
|
||||
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region);
|
||||
}
|
||||
else if (region != None)
|
||||
{
|
||||
info->pending_input_region = XFixesCreateRegion (xdpy, NULL, 0);
|
||||
XFixesCopyRegion (xdpy, info->pending_input_region, region);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mutter_empty_stage_input_region (MetaScreen *screen)
|
||||
{
|
||||
/* Using a static region here is a bit hacky, but Metacity never opens more than
|
||||
* one XDisplay, so it works fine. */
|
||||
static XserverRegion region = None;
|
||||
|
||||
if (region == None)
|
||||
{
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
region = XFixesCreateRegion (xdpy, NULL, 0);
|
||||
}
|
||||
|
||||
mutter_set_stage_input_region (screen, region);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_cmp_manage_screen (MetaCompositor *compositor,
|
||||
MetaScreen *screen)
|
||||
@ -1914,15 +1956,22 @@ clutter_cmp_manage_screen (MetaCompositor *compositor,
|
||||
/*
|
||||
* Delay the creation of the overlay window as long as we can, to avoid
|
||||
* blanking out the screen. This means that during the plugin loading, the
|
||||
* overlay window is not accessible, and so the plugins cannot do stuff
|
||||
* like changing input shape; if that is required, the plugin should hook into
|
||||
* "show" signal on stage, and do its stuff there.
|
||||
* overlay window is not accessible; if the plugin needs to access it
|
||||
* directly, it should hook into the "show" signal on stage, and do
|
||||
* its stuff there.
|
||||
*/
|
||||
info->output = get_output_window (screen);
|
||||
XReparentWindow (xdisplay, xwin, info->output, 0, 0);
|
||||
|
||||
show_overlay_window (xdisplay, xwin, info->output);
|
||||
|
||||
if (info->pending_input_region != None)
|
||||
{
|
||||
mutter_set_stage_input_region (screen, info->pending_input_region);
|
||||
XFixesDestroyRegion (xdisplay, info->pending_input_region);
|
||||
info->pending_input_region = None;
|
||||
}
|
||||
|
||||
clutter_actor_show (info->overlay_group);
|
||||
clutter_actor_show (info->stage);
|
||||
#endif
|
||||
|
@ -408,34 +408,11 @@ mutter_plugin_set_stage_reactive (MutterPlugin *plugin,
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage, xoverlay;
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = mutter_get_stage_for_screen (screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = mutter_get_overlay_window (screen);
|
||||
|
||||
static XserverRegion region = None;
|
||||
|
||||
if (region == None)
|
||||
region = XFixesCreateRegion (xdpy, NULL, 0);
|
||||
|
||||
if (reactive)
|
||||
{
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage,
|
||||
ShapeInput, 0, 0, None);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay,
|
||||
ShapeInput, 0, 0, None);
|
||||
}
|
||||
mutter_set_stage_input_region (screen, None);
|
||||
else
|
||||
{
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage,
|
||||
ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay,
|
||||
ShapeInput, 0, 0, region);
|
||||
}
|
||||
mutter_empty_stage_input_region (screen);
|
||||
}
|
||||
|
||||
void
|
||||
@ -446,25 +423,16 @@ mutter_plugin_set_stage_input_area (MutterPlugin *plugin,
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage, xoverlay;
|
||||
ClutterActor *stage;
|
||||
XRectangle rect;
|
||||
XserverRegion region;
|
||||
|
||||
stage = mutter_get_stage_for_screen (screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = mutter_get_overlay_window (screen);
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
region = XFixesCreateRegion (xdpy, &rect, 1);
|
||||
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
|
||||
|
||||
mutter_set_stage_input_region (screen, region);
|
||||
XFixesDestroyRegion (xdpy, region);
|
||||
}
|
||||
|
||||
@ -474,17 +442,8 @@ mutter_plugin_set_stage_input_region (MutterPlugin *plugin,
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage, xoverlay;
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = mutter_get_stage_for_screen (screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = mutter_get_overlay_window (screen);
|
||||
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
|
||||
mutter_set_stage_input_region (screen, region);
|
||||
}
|
||||
|
||||
GList *
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define MUTTER_H_
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "types.h"
|
||||
@ -80,4 +81,8 @@ Window mutter_get_overlay_window (MetaScreen *screen);
|
||||
GList * mutter_get_windows (MetaScreen *screen);
|
||||
ClutterActor * mutter_get_window_group_for_screen (MetaScreen *screen);
|
||||
|
||||
void mutter_set_stage_input_region (MetaScreen *screen,
|
||||
XserverRegion region);
|
||||
void mutter_empty_stage_input_region (MetaScreen *screen);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user