Do not use the default stage
https://bugzilla.gnome.org/show_bug.cgi?id=664052
This commit is contained in:
parent
69e26c6dee
commit
faff0738eb
@ -44,7 +44,7 @@ const Magnifier = new Lang.Class({
|
|||||||
this._zoomRegions = [];
|
this._zoomRegions = [];
|
||||||
|
|
||||||
// Create small clutter tree for the magnified mouse.
|
// Create small clutter tree for the magnified mouse.
|
||||||
let xfixesCursor = Shell.XFixesCursor.get_default();
|
let xfixesCursor = Shell.XFixesCursor.get_for_stage(global.stage);
|
||||||
this._mouseSprite = new Clutter.Texture();
|
this._mouseSprite = new Clutter.Texture();
|
||||||
xfixesCursor.update_texture_image(this._mouseSprite);
|
xfixesCursor.update_texture_image(this._mouseSprite);
|
||||||
this._cursorRoot = new Clutter.Group();
|
this._cursorRoot = new Clutter.Group();
|
||||||
|
@ -323,7 +323,7 @@ gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((xev->xany.type == EnterNotify || xev->xany.type == LeaveNotify)
|
if ((xev->xany.type == EnterNotify || xev->xany.type == LeaveNotify)
|
||||||
&& xev->xcrossing.window == clutter_x11_get_stage_window (CLUTTER_STAGE (clutter_stage_get_default ())))
|
&& xev->xcrossing.window == clutter_x11_get_stage_window (CLUTTER_STAGE (meta_plugin_get_stage (plugin))))
|
||||||
{
|
{
|
||||||
/* If the pointer enters a child of the stage window (eg, a
|
/* If the pointer enters a child of the stage window (eg, a
|
||||||
* trayicon), we want to consider it to still be in the stage,
|
* trayicon), we want to consider it to still be in the stage,
|
||||||
|
249
src/main.c
249
src/main.c
@ -8,7 +8,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <cogl-pango/cogl-pango.h>
|
|
||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
#include <clutter/x11/clutter-x11.h>
|
#include <clutter/x11/clutter-x11.h>
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
@ -159,157 +158,6 @@ shell_dbus_init (gboolean replace)
|
|||||||
g_object_unref (session);
|
g_object_unref (session);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
constrain_tooltip (StTooltip *tooltip,
|
|
||||||
const ClutterGeometry *geometry,
|
|
||||||
ClutterGeometry *adjusted_geometry,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
const ClutterGeometry *tip_area = st_tooltip_get_tip_area (tooltip);
|
|
||||||
ShellGlobal *global = shell_global_get ();
|
|
||||||
MetaScreen *screen = shell_global_get_screen (global);
|
|
||||||
int n_monitors = meta_screen_get_n_monitors (screen);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
*adjusted_geometry = *geometry;
|
|
||||||
|
|
||||||
/* A point that determines what screen we'll constrain to */
|
|
||||||
int x = tip_area->x + tip_area->width / 2;
|
|
||||||
int y = tip_area->y + tip_area->height / 2;
|
|
||||||
|
|
||||||
for (i = 0; i < n_monitors; i++)
|
|
||||||
{
|
|
||||||
MetaRectangle rect;
|
|
||||||
meta_screen_get_monitor_geometry (screen, i, &rect);
|
|
||||||
if (x >= rect.x && x < rect.x + rect.width &&
|
|
||||||
y >= rect.y && y < rect.y + rect.height)
|
|
||||||
{
|
|
||||||
if (adjusted_geometry->x + adjusted_geometry->width > rect.x + rect.width)
|
|
||||||
adjusted_geometry->x = rect.x + rect.width - adjusted_geometry->width;
|
|
||||||
if (adjusted_geometry->x < rect.x)
|
|
||||||
adjusted_geometry->x = rect.x;
|
|
||||||
|
|
||||||
if (adjusted_geometry->y + adjusted_geometry->height > rect.y + rect.height)
|
|
||||||
adjusted_geometry->y = rect.y + rect.height - adjusted_geometry->height;
|
|
||||||
if (adjusted_geometry->y < rect.y)
|
|
||||||
adjusted_geometry->y = rect.y;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
update_font_options (GtkSettings *settings)
|
|
||||||
{
|
|
||||||
StThemeContext *context;
|
|
||||||
ClutterStage *stage;
|
|
||||||
ClutterBackend *backend;
|
|
||||||
gint dpi;
|
|
||||||
gint hinting;
|
|
||||||
gchar *hint_style_str;
|
|
||||||
cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_NONE;
|
|
||||||
gint antialias;
|
|
||||||
cairo_antialias_t antialias_mode = CAIRO_ANTIALIAS_NONE;
|
|
||||||
cairo_font_options_t *options;
|
|
||||||
|
|
||||||
g_object_get (settings,
|
|
||||||
"gtk-xft-dpi", &dpi,
|
|
||||||
"gtk-xft-antialias", &antialias,
|
|
||||||
"gtk-xft-hinting", &hinting,
|
|
||||||
"gtk-xft-hintstyle", &hint_style_str,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
stage = CLUTTER_STAGE (clutter_stage_get_default ());
|
|
||||||
context = st_theme_context_get_for_stage (stage);
|
|
||||||
|
|
||||||
if (dpi != -1)
|
|
||||||
/* GTK stores resolution as 1024 * dots/inch */
|
|
||||||
st_theme_context_set_resolution (context, dpi / 1024);
|
|
||||||
else
|
|
||||||
st_theme_context_set_default_resolution (context);
|
|
||||||
|
|
||||||
st_tooltip_set_constrain_func (stage, constrain_tooltip, NULL, NULL);
|
|
||||||
|
|
||||||
/* Clutter (as of 0.9) passes comprehensively wrong font options
|
|
||||||
* override whatever set_font_flags() did above.
|
|
||||||
*
|
|
||||||
* http://bugzilla.openedhand.com/show_bug.cgi?id=1456
|
|
||||||
*/
|
|
||||||
backend = clutter_get_default_backend ();
|
|
||||||
options = cairo_font_options_create ();
|
|
||||||
|
|
||||||
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
|
|
||||||
|
|
||||||
if (hinting >= 0 && !hinting)
|
|
||||||
{
|
|
||||||
hint_style = CAIRO_HINT_STYLE_NONE;
|
|
||||||
}
|
|
||||||
else if (hint_style_str)
|
|
||||||
{
|
|
||||||
if (strcmp (hint_style_str, "hintnone") == 0)
|
|
||||||
hint_style = CAIRO_HINT_STYLE_NONE;
|
|
||||||
else if (strcmp (hint_style_str, "hintslight") == 0)
|
|
||||||
hint_style = CAIRO_HINT_STYLE_SLIGHT;
|
|
||||||
else if (strcmp (hint_style_str, "hintmedium") == 0)
|
|
||||||
hint_style = CAIRO_HINT_STYLE_MEDIUM;
|
|
||||||
else if (strcmp (hint_style_str, "hintfull") == 0)
|
|
||||||
hint_style = CAIRO_HINT_STYLE_FULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (hint_style_str);
|
|
||||||
|
|
||||||
cairo_font_options_set_hint_style (options, hint_style);
|
|
||||||
|
|
||||||
/* We don't want to turn on subpixel anti-aliasing; since Clutter
|
|
||||||
* doesn't currently have the code to support ARGB masks,
|
|
||||||
* generating them then squashing them back to A8 is pointless.
|
|
||||||
*/
|
|
||||||
antialias_mode = (antialias < 0 || antialias) ? CAIRO_ANTIALIAS_GRAY
|
|
||||||
: CAIRO_ANTIALIAS_NONE;
|
|
||||||
|
|
||||||
cairo_font_options_set_antialias (options, antialias_mode);
|
|
||||||
|
|
||||||
clutter_backend_set_font_options (backend, options);
|
|
||||||
cairo_font_options_destroy (options);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
settings_notify_cb (GtkSettings *settings,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
update_font_options (settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
shell_fonts_init (void)
|
|
||||||
{
|
|
||||||
GtkSettings *settings;
|
|
||||||
CoglPangoFontMap *fontmap;
|
|
||||||
|
|
||||||
/* Disable text mipmapping; it causes problems on pre-GEM Intel
|
|
||||||
* drivers and we should just be rendering text at the right
|
|
||||||
* size rather than scaling it. If we do effects where we dynamically
|
|
||||||
* zoom labels, then we might want to reconsider.
|
|
||||||
*/
|
|
||||||
fontmap = COGL_PANGO_FONT_MAP (clutter_get_font_map ());
|
|
||||||
cogl_pango_font_map_set_use_mipmapping (fontmap, FALSE);
|
|
||||||
|
|
||||||
settings = gtk_settings_get_default ();
|
|
||||||
g_object_connect (settings,
|
|
||||||
"signal::notify::gtk-xft-dpi",
|
|
||||||
G_CALLBACK (settings_notify_cb), NULL,
|
|
||||||
"signal::notify::gtk-xft-antialias",
|
|
||||||
G_CALLBACK (settings_notify_cb), NULL,
|
|
||||||
"signal::notify::gtk-xft-hinting",
|
|
||||||
G_CALLBACK (settings_notify_cb), NULL,
|
|
||||||
"signal::notify::gtk-xft-hintstyle",
|
|
||||||
G_CALLBACK (settings_notify_cb), NULL,
|
|
||||||
NULL);
|
|
||||||
update_font_options (settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
shell_prefs_init (void)
|
shell_prefs_init (void)
|
||||||
{
|
{
|
||||||
@ -323,100 +171,6 @@ shell_prefs_init (void)
|
|||||||
OVERRIDES_SCHEMA);
|
OVERRIDES_SCHEMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is an IBus workaround. The flow of events with IBus is that every time
|
|
||||||
* it gets gets a key event, it:
|
|
||||||
*
|
|
||||||
* Sends it to the daemon via D-Bus asynchronously
|
|
||||||
* When it gets an reply, synthesizes a new GdkEvent and puts it into the
|
|
||||||
* GDK event queue with gdk_event_put(), including
|
|
||||||
* IBUS_FORWARD_MASK = 1 << 25 in the state to prevent a loop.
|
|
||||||
*
|
|
||||||
* (Normally, IBus uses the GTK+ key snooper mechanism to get the key
|
|
||||||
* events early, but since our key events aren't visible to GTK+ key snoopers,
|
|
||||||
* IBus will instead get the events via the standard
|
|
||||||
* GtkIMContext.filter_keypress() mechanism.)
|
|
||||||
*
|
|
||||||
* There are a number of potential problems here; probably the worst
|
|
||||||
* problem is that IBus doesn't forward the timestamp with the event
|
|
||||||
* so that every key event that gets delivered ends up with
|
|
||||||
* GDK_CURRENT_TIME. This creates some very subtle bugs; for example
|
|
||||||
* if you have IBus running and a keystroke is used to trigger
|
|
||||||
* launching an application, focus stealing prevention won't work
|
|
||||||
* right. http://code.google.com/p/ibus/issues/detail?id=1184
|
|
||||||
*
|
|
||||||
* In any case, our normal flow of key events is:
|
|
||||||
*
|
|
||||||
* GDK filter function => clutter_x11_handle_event => clutter actor
|
|
||||||
*
|
|
||||||
* So, if we see a key event that gets delivered via the GDK event handler
|
|
||||||
* function - then we know it must be one of these synthesized events, and
|
|
||||||
* we should push it back to clutter.
|
|
||||||
*
|
|
||||||
* To summarize, the full key event flow with IBus is:
|
|
||||||
*
|
|
||||||
* GDK filter function
|
|
||||||
* => Mutter
|
|
||||||
* => gnome_shell_plugin_xevent_filter()
|
|
||||||
* => clutter_x11_handle_event()
|
|
||||||
* => clutter event delivery to actor
|
|
||||||
* => gtk_im_context_filter_event()
|
|
||||||
* => sent to IBus daemon
|
|
||||||
* => response received from IBus daemon
|
|
||||||
* => gdk_event_put()
|
|
||||||
* => GDK event handler
|
|
||||||
* => <this function>
|
|
||||||
* => clutter_event_put()
|
|
||||||
* => clutter event delivery to actor
|
|
||||||
*
|
|
||||||
* Anything else we see here we just pass on to the normal GDK event handler
|
|
||||||
* gtk_main_do_event().
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
gnome_shell_gdk_event_handler (GdkEvent *event_gdk,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
if (event_gdk->type == GDK_KEY_PRESS || event_gdk->type == GDK_KEY_RELEASE)
|
|
||||||
{
|
|
||||||
ClutterActor *stage;
|
|
||||||
Window stage_xwindow;
|
|
||||||
|
|
||||||
stage = clutter_stage_get_default ();
|
|
||||||
stage_xwindow = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
|
||||||
|
|
||||||
if (GDK_WINDOW_XID (event_gdk->key.window) == stage_xwindow)
|
|
||||||
{
|
|
||||||
ClutterDeviceManager *device_manager = clutter_device_manager_get_default ();
|
|
||||||
ClutterInputDevice *keyboard = clutter_device_manager_get_core_device (device_manager,
|
|
||||||
CLUTTER_KEYBOARD_DEVICE);
|
|
||||||
|
|
||||||
ClutterEvent *event_clutter = clutter_event_new ((event_gdk->type == GDK_KEY_PRESS) ?
|
|
||||||
CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE);
|
|
||||||
event_clutter->key.time = event_gdk->key.time;
|
|
||||||
event_clutter->key.flags = CLUTTER_EVENT_NONE;
|
|
||||||
event_clutter->key.stage = CLUTTER_STAGE (stage);
|
|
||||||
event_clutter->key.source = NULL;
|
|
||||||
|
|
||||||
/* This depends on ClutterModifierType and GdkModifierType being
|
|
||||||
* identical, which they are currently. (They both match the X
|
|
||||||
* modifier state in the low 16-bits and have the same extensions.) */
|
|
||||||
event_clutter->key.modifier_state = event_gdk->key.state;
|
|
||||||
|
|
||||||
event_clutter->key.keyval = event_gdk->key.keyval;
|
|
||||||
event_clutter->key.hardware_keycode = event_gdk->key.hardware_keycode;
|
|
||||||
event_clutter->key.unicode_value = gdk_keyval_to_unicode (event_clutter->key.keyval);
|
|
||||||
event_clutter->key.device = keyboard;
|
|
||||||
|
|
||||||
clutter_event_put (event_clutter);
|
|
||||||
clutter_event_free (event_clutter);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_main_do_event (event_gdk);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
malloc_statistics_callback (ShellPerfLog *perf_log,
|
malloc_statistics_callback (ShellPerfLog *perf_log,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
@ -559,12 +313,9 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
shell_dbus_init (meta_get_replace_current_wm ());
|
shell_dbus_init (meta_get_replace_current_wm ());
|
||||||
shell_a11y_init ();
|
shell_a11y_init ();
|
||||||
shell_fonts_init ();
|
|
||||||
shell_perf_log_init ();
|
shell_perf_log_init ();
|
||||||
shell_prefs_init ();
|
shell_prefs_init ();
|
||||||
|
|
||||||
gdk_event_handler_set (gnome_shell_gdk_event_handler, NULL, NULL);
|
|
||||||
|
|
||||||
g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
|
g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
|
||||||
#if HAVE_BLUETOOTH
|
#if HAVE_BLUETOOTH
|
||||||
g_irepository_prepend_search_path (BLUETOOTH_DIR);
|
g_irepository_prepend_search_path (BLUETOOTH_DIR);
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <X11/extensions/Xfixes.h>
|
#include <X11/extensions/Xfixes.h>
|
||||||
|
#include <cogl-pango/cogl-pango.h>
|
||||||
#include <canberra.h>
|
#include <canberra.h>
|
||||||
#include <clutter/glx/clutter-glx.h>
|
#include <clutter/glx/clutter-glx.h>
|
||||||
#include <clutter/x11/clutter-x11.h>
|
#include <clutter/x11/clutter-x11.h>
|
||||||
@ -793,6 +794,249 @@ global_stage_after_paint (ClutterStage *stage,
|
|||||||
"clutter.stagePaintDone");
|
"clutter.stagePaintDone");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constrain_tooltip (StTooltip *tooltip,
|
||||||
|
const ClutterGeometry *geometry,
|
||||||
|
ClutterGeometry *adjusted_geometry,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
const ClutterGeometry *tip_area = st_tooltip_get_tip_area (tooltip);
|
||||||
|
ShellGlobal *global = shell_global_get ();
|
||||||
|
MetaScreen *screen = shell_global_get_screen (global);
|
||||||
|
int n_monitors = meta_screen_get_n_monitors (screen);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*adjusted_geometry = *geometry;
|
||||||
|
|
||||||
|
/* A point that determines what screen we'll constrain to */
|
||||||
|
int x = tip_area->x + tip_area->width / 2;
|
||||||
|
int y = tip_area->y + tip_area->height / 2;
|
||||||
|
|
||||||
|
for (i = 0; i < n_monitors; i++)
|
||||||
|
{
|
||||||
|
MetaRectangle rect;
|
||||||
|
meta_screen_get_monitor_geometry (screen, i, &rect);
|
||||||
|
if (x >= rect.x && x < rect.x + rect.width &&
|
||||||
|
y >= rect.y && y < rect.y + rect.height)
|
||||||
|
{
|
||||||
|
if (adjusted_geometry->x + adjusted_geometry->width > rect.x + rect.width)
|
||||||
|
adjusted_geometry->x = rect.x + rect.width - adjusted_geometry->width;
|
||||||
|
if (adjusted_geometry->x < rect.x)
|
||||||
|
adjusted_geometry->x = rect.x;
|
||||||
|
|
||||||
|
if (adjusted_geometry->y + adjusted_geometry->height > rect.y + rect.height)
|
||||||
|
adjusted_geometry->y = rect.y + rect.height - adjusted_geometry->height;
|
||||||
|
if (adjusted_geometry->y < rect.y)
|
||||||
|
adjusted_geometry->y = rect.y;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_font_options (GtkSettings *settings,
|
||||||
|
ClutterStage *stage)
|
||||||
|
{
|
||||||
|
StThemeContext *context;
|
||||||
|
ClutterBackend *backend;
|
||||||
|
gint dpi;
|
||||||
|
gint hinting;
|
||||||
|
gchar *hint_style_str;
|
||||||
|
cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_NONE;
|
||||||
|
gint antialias;
|
||||||
|
cairo_antialias_t antialias_mode = CAIRO_ANTIALIAS_NONE;
|
||||||
|
cairo_font_options_t *options;
|
||||||
|
|
||||||
|
g_object_get (settings,
|
||||||
|
"gtk-xft-dpi", &dpi,
|
||||||
|
"gtk-xft-antialias", &antialias,
|
||||||
|
"gtk-xft-hinting", &hinting,
|
||||||
|
"gtk-xft-hintstyle", &hint_style_str,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
context = st_theme_context_get_for_stage (stage);
|
||||||
|
|
||||||
|
if (dpi != -1)
|
||||||
|
/* GTK stores resolution as 1024 * dots/inch */
|
||||||
|
st_theme_context_set_resolution (context, dpi / 1024);
|
||||||
|
else
|
||||||
|
st_theme_context_set_default_resolution (context);
|
||||||
|
|
||||||
|
st_tooltip_set_constrain_func (stage, constrain_tooltip, NULL, NULL);
|
||||||
|
|
||||||
|
/* Clutter (as of 0.9) passes comprehensively wrong font options
|
||||||
|
* override whatever set_font_flags() did above.
|
||||||
|
*
|
||||||
|
* http://bugzilla.openedhand.com/show_bug.cgi?id=1456
|
||||||
|
*/
|
||||||
|
backend = clutter_get_default_backend ();
|
||||||
|
options = cairo_font_options_create ();
|
||||||
|
|
||||||
|
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
|
||||||
|
|
||||||
|
if (hinting >= 0 && !hinting)
|
||||||
|
{
|
||||||
|
hint_style = CAIRO_HINT_STYLE_NONE;
|
||||||
|
}
|
||||||
|
else if (hint_style_str)
|
||||||
|
{
|
||||||
|
if (strcmp (hint_style_str, "hintnone") == 0)
|
||||||
|
hint_style = CAIRO_HINT_STYLE_NONE;
|
||||||
|
else if (strcmp (hint_style_str, "hintslight") == 0)
|
||||||
|
hint_style = CAIRO_HINT_STYLE_SLIGHT;
|
||||||
|
else if (strcmp (hint_style_str, "hintmedium") == 0)
|
||||||
|
hint_style = CAIRO_HINT_STYLE_MEDIUM;
|
||||||
|
else if (strcmp (hint_style_str, "hintfull") == 0)
|
||||||
|
hint_style = CAIRO_HINT_STYLE_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (hint_style_str);
|
||||||
|
|
||||||
|
cairo_font_options_set_hint_style (options, hint_style);
|
||||||
|
|
||||||
|
/* We don't want to turn on subpixel anti-aliasing; since Clutter
|
||||||
|
* doesn't currently have the code to support ARGB masks,
|
||||||
|
* generating them then squashing them back to A8 is pointless.
|
||||||
|
*/
|
||||||
|
antialias_mode = (antialias < 0 || antialias) ? CAIRO_ANTIALIAS_GRAY
|
||||||
|
: CAIRO_ANTIALIAS_NONE;
|
||||||
|
|
||||||
|
cairo_font_options_set_antialias (options, antialias_mode);
|
||||||
|
|
||||||
|
clutter_backend_set_font_options (backend, options);
|
||||||
|
cairo_font_options_destroy (options);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
settings_notify_cb (GtkSettings *settings,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
update_font_options (settings, CLUTTER_STAGE (data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_fonts_init (ClutterStage *stage)
|
||||||
|
{
|
||||||
|
GtkSettings *settings;
|
||||||
|
CoglPangoFontMap *fontmap;
|
||||||
|
|
||||||
|
/* Disable text mipmapping; it causes problems on pre-GEM Intel
|
||||||
|
* drivers and we should just be rendering text at the right
|
||||||
|
* size rather than scaling it. If we do effects where we dynamically
|
||||||
|
* zoom labels, then we might want to reconsider.
|
||||||
|
*/
|
||||||
|
fontmap = COGL_PANGO_FONT_MAP (clutter_get_font_map ());
|
||||||
|
cogl_pango_font_map_set_use_mipmapping (fontmap, FALSE);
|
||||||
|
|
||||||
|
settings = gtk_settings_get_default ();
|
||||||
|
g_object_connect (settings,
|
||||||
|
"signal::notify::gtk-xft-dpi",
|
||||||
|
G_CALLBACK (settings_notify_cb), stage,
|
||||||
|
"signal::notify::gtk-xft-antialias",
|
||||||
|
G_CALLBACK (settings_notify_cb), stage,
|
||||||
|
"signal::notify::gtk-xft-hinting",
|
||||||
|
G_CALLBACK (settings_notify_cb), stage,
|
||||||
|
"signal::notify::gtk-xft-hintstyle",
|
||||||
|
G_CALLBACK (settings_notify_cb), stage,
|
||||||
|
NULL);
|
||||||
|
update_font_options (settings, stage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is an IBus workaround. The flow of events with IBus is that every time
|
||||||
|
* it gets gets a key event, it:
|
||||||
|
*
|
||||||
|
* Sends it to the daemon via D-Bus asynchronously
|
||||||
|
* When it gets an reply, synthesizes a new GdkEvent and puts it into the
|
||||||
|
* GDK event queue with gdk_event_put(), including
|
||||||
|
* IBUS_FORWARD_MASK = 1 << 25 in the state to prevent a loop.
|
||||||
|
*
|
||||||
|
* (Normally, IBus uses the GTK+ key snooper mechanism to get the key
|
||||||
|
* events early, but since our key events aren't visible to GTK+ key snoopers,
|
||||||
|
* IBus will instead get the events via the standard
|
||||||
|
* GtkIMContext.filter_keypress() mechanism.)
|
||||||
|
*
|
||||||
|
* There are a number of potential problems here; probably the worst
|
||||||
|
* problem is that IBus doesn't forward the timestamp with the event
|
||||||
|
* so that every key event that gets delivered ends up with
|
||||||
|
* GDK_CURRENT_TIME. This creates some very subtle bugs; for example
|
||||||
|
* if you have IBus running and a keystroke is used to trigger
|
||||||
|
* launching an application, focus stealing prevention won't work
|
||||||
|
* right. http://code.google.com/p/ibus/issues/detail?id=1184
|
||||||
|
*
|
||||||
|
* In any case, our normal flow of key events is:
|
||||||
|
*
|
||||||
|
* GDK filter function => clutter_x11_handle_event => clutter actor
|
||||||
|
*
|
||||||
|
* So, if we see a key event that gets delivered via the GDK event handler
|
||||||
|
* function - then we know it must be one of these synthesized events, and
|
||||||
|
* we should push it back to clutter.
|
||||||
|
*
|
||||||
|
* To summarize, the full key event flow with IBus is:
|
||||||
|
*
|
||||||
|
* GDK filter function
|
||||||
|
* => Mutter
|
||||||
|
* => gnome_shell_plugin_xevent_filter()
|
||||||
|
* => clutter_x11_handle_event()
|
||||||
|
* => clutter event delivery to actor
|
||||||
|
* => gtk_im_context_filter_event()
|
||||||
|
* => sent to IBus daemon
|
||||||
|
* => response received from IBus daemon
|
||||||
|
* => gdk_event_put()
|
||||||
|
* => GDK event handler
|
||||||
|
* => <this function>
|
||||||
|
* => clutter_event_put()
|
||||||
|
* => clutter event delivery to actor
|
||||||
|
*
|
||||||
|
* Anything else we see here we just pass on to the normal GDK event handler
|
||||||
|
* gtk_main_do_event().
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
gnome_shell_gdk_event_handler (GdkEvent *event_gdk,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
if (event_gdk->type == GDK_KEY_PRESS || event_gdk->type == GDK_KEY_RELEASE)
|
||||||
|
{
|
||||||
|
ClutterActor *stage;
|
||||||
|
Window stage_xwindow;
|
||||||
|
|
||||||
|
stage = CLUTTER_ACTOR (data);
|
||||||
|
stage_xwindow = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||||
|
|
||||||
|
if (GDK_WINDOW_XID (event_gdk->key.window) == stage_xwindow)
|
||||||
|
{
|
||||||
|
ClutterDeviceManager *device_manager = clutter_device_manager_get_default ();
|
||||||
|
ClutterInputDevice *keyboard = clutter_device_manager_get_core_device (device_manager,
|
||||||
|
CLUTTER_KEYBOARD_DEVICE);
|
||||||
|
|
||||||
|
ClutterEvent *event_clutter = clutter_event_new ((event_gdk->type == GDK_KEY_PRESS) ?
|
||||||
|
CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE);
|
||||||
|
event_clutter->key.time = event_gdk->key.time;
|
||||||
|
event_clutter->key.flags = CLUTTER_EVENT_NONE;
|
||||||
|
event_clutter->key.stage = CLUTTER_STAGE (stage);
|
||||||
|
event_clutter->key.source = NULL;
|
||||||
|
|
||||||
|
/* This depends on ClutterModifierType and GdkModifierType being
|
||||||
|
* identical, which they are currently. (They both match the X
|
||||||
|
* modifier state in the low 16-bits and have the same extensions.) */
|
||||||
|
event_clutter->key.modifier_state = event_gdk->key.state;
|
||||||
|
|
||||||
|
event_clutter->key.keyval = event_gdk->key.keyval;
|
||||||
|
event_clutter->key.hardware_keycode = event_gdk->key.hardware_keycode;
|
||||||
|
event_clutter->key.unicode_value = gdk_keyval_to_unicode (event_clutter->key.keyval);
|
||||||
|
event_clutter->key.device = keyboard;
|
||||||
|
|
||||||
|
clutter_event_put (event_clutter);
|
||||||
|
clutter_event_free (event_clutter);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_main_do_event (event_gdk);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_shell_global_set_plugin (ShellGlobal *global,
|
_shell_global_set_plugin (ShellGlobal *global,
|
||||||
MetaPlugin *plugin)
|
MetaPlugin *plugin)
|
||||||
@ -838,6 +1082,10 @@ _shell_global_set_plugin (ShellGlobal *global,
|
|||||||
g_signal_connect (global->meta_display, "notify::focus-window",
|
g_signal_connect (global->meta_display, "notify::focus-window",
|
||||||
G_CALLBACK (focus_window_changed), global);
|
G_CALLBACK (focus_window_changed), global);
|
||||||
|
|
||||||
|
shell_fonts_init (global->stage);
|
||||||
|
|
||||||
|
gdk_event_handler_set (gnome_shell_gdk_event_handler, global->stage, NULL);
|
||||||
|
|
||||||
global->focus_manager = st_focus_manager_get_for_stage (global->stage);
|
global->focus_manager = st_focus_manager_get_for_stage (global->stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,19 +321,29 @@ shell_xfixes_cursor_class_init (ShellXFixesCursorClass *klass)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shell_xfixes_cursor_get_default:
|
* shell_xfixes_cursor_get_for_stage:
|
||||||
|
* @stage: (transfer none): The #ClutterStage to get the cursor for
|
||||||
*
|
*
|
||||||
* Return value: (transfer none): The global #ShellXFixesCursor singleton
|
* Return value: (transfer none): A #ShellXFixesCursor instance
|
||||||
*/
|
*/
|
||||||
ShellXFixesCursor *
|
ShellXFixesCursor *
|
||||||
shell_xfixes_cursor_get_default ()
|
shell_xfixes_cursor_get_for_stage (ClutterStage *stage)
|
||||||
{
|
{
|
||||||
static ShellXFixesCursor *instance = NULL;
|
ShellXFixesCursor *instance;
|
||||||
|
static GQuark xfixes_cursor_quark;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (xfixes_cursor_quark == 0))
|
||||||
|
xfixes_cursor_quark = g_quark_from_static_string ("gnome-shell-xfixes-cursor");
|
||||||
|
|
||||||
|
instance = g_object_get_qdata (G_OBJECT (stage), xfixes_cursor_quark);
|
||||||
|
|
||||||
if (instance == NULL)
|
if (instance == NULL)
|
||||||
|
{
|
||||||
instance = g_object_new (SHELL_TYPE_XFIXES_CURSOR,
|
instance = g_object_new (SHELL_TYPE_XFIXES_CURSOR,
|
||||||
"stage", clutter_stage_get_default (),
|
"stage", stage,
|
||||||
NULL);
|
NULL);
|
||||||
|
g_object_set_qdata (G_OBJECT (stage), xfixes_cursor_quark, instance);
|
||||||
|
}
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ typedef struct _ShellXFixesCursorClass ShellXFixesCursorClass;
|
|||||||
|
|
||||||
GType shell_xfixes_cursor_get_type (void) G_GNUC_CONST;
|
GType shell_xfixes_cursor_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
ShellXFixesCursor *shell_xfixes_cursor_get_default (void);
|
ShellXFixesCursor *shell_xfixes_cursor_get_for_stage (ClutterStage *stage);
|
||||||
|
|
||||||
void shell_xfixes_cursor_show (ShellXFixesCursor *xfixes_cursor);
|
void shell_xfixes_cursor_show (ShellXFixesCursor *xfixes_cursor);
|
||||||
void shell_xfixes_cursor_hide (ShellXFixesCursor *xfixes_cursor);
|
void shell_xfixes_cursor_hide (ShellXFixesCursor *xfixes_cursor);
|
||||||
|
@ -432,7 +432,7 @@ main (int argc, char **argv)
|
|||||||
theme = st_theme_new ("st/test-theme.css",
|
theme = st_theme_new ("st/test-theme.css",
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
stage = clutter_stage_get_default ();
|
stage = clutter_stage_new ();
|
||||||
context = st_theme_context_get_for_stage (CLUTTER_STAGE (stage));
|
context = st_theme_context_get_for_stage (CLUTTER_STAGE (stage));
|
||||||
st_theme_context_set_theme (context, theme);
|
st_theme_context_set_theme (context, theme);
|
||||||
st_theme_context_set_resolution (context, 96.);
|
st_theme_context_set_resolution (context, 96.);
|
||||||
|
@ -36,7 +36,8 @@ int main (int argc, char **argv)
|
|||||||
clutter_color_from_string (&red, "red");
|
clutter_color_from_string (&red, "red");
|
||||||
clutter_color_from_string (&green, "green");
|
clutter_color_from_string (&green, "green");
|
||||||
clutter_color_from_string (&blue, "blue");
|
clutter_color_from_string (&blue, "blue");
|
||||||
stage = clutter_stage_get_default ();
|
stage = clutter_stage_new ();
|
||||||
|
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
|
||||||
|
|
||||||
text = g_object_new (CLUTTER_TYPE_TEXT,
|
text = g_object_new (CLUTTER_TYPE_TEXT,
|
||||||
"text", "Red",
|
"text", "Red",
|
||||||
|
Loading…
Reference in New Issue
Block a user