Use libmutter-wm, and build a real gnome-shell binary
Build gnome-shell as a binary linked against libmutter-wm, instead of a module to be loaded by libmutter-wm. Move the majority of initialization-type stuff from gnome_shell_plugin_start() into main(). We still build libgnome-shell as a shared library, so that the linker doesn't discard all the methods that are never called from C. https://bugzilla.gnome.org/show_bug.cgi?id=641724
This commit is contained in:
parent
c4dad3d2c1
commit
ae96b0c971
2
.gitignore
vendored
2
.gitignore
vendored
@ -44,7 +44,7 @@ src/calendar-server/org.gnome.Shell.CalendarServer.service
|
||||
src/gnome-shell
|
||||
src/gnome-shell-calendar-server
|
||||
src/gnome-shell-extension-tool
|
||||
src/gnome-shell-installed
|
||||
src/gnome-shell-real
|
||||
src/gnome-shell-jhbuild
|
||||
src/run-js-test
|
||||
src/test-recorder
|
||||
|
46
configure.ac
46
configure.ac
@ -74,20 +74,20 @@ TELEPATHY_GLIB_MIN_VERSION=0.13.12
|
||||
POLKIT_MIN_VERSION=0.100
|
||||
|
||||
# Collect more than 20 libraries for a prize!
|
||||
PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION
|
||||
gio-unix-2.0 dbus-glib-1 libxml-2.0
|
||||
gtk+-3.0 >= $GTK_MIN_VERSION
|
||||
mutter-plugins >= $MUTTER_MIN_VERSION
|
||||
gjs-internals-1.0 >= $GJS_MIN_VERSION
|
||||
libgnome-menu $recorder_modules gconf-2.0
|
||||
gdk-x11-3.0
|
||||
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
|
||||
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
|
||||
libstartup-notification-1.0
|
||||
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
|
||||
libcanberra
|
||||
telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION
|
||||
polkit-agent-1 >= $POLKIT_MIN_VERSION)
|
||||
PKG_CHECK_MODULES(GNOME_SHELL, gio-2.0 >= $GIO_MIN_VERSION
|
||||
gio-unix-2.0 dbus-glib-1 libxml-2.0
|
||||
gtk+-3.0 >= $GTK_MIN_VERSION
|
||||
libmutter-wm >= $MUTTER_MIN_VERSION
|
||||
gjs-internals-1.0 >= $GJS_MIN_VERSION
|
||||
libgnome-menu $recorder_modules gconf-2.0
|
||||
gdk-x11-3.0
|
||||
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
|
||||
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
|
||||
libstartup-notification-1.0
|
||||
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
|
||||
libcanberra
|
||||
telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION
|
||||
polkit-agent-1 >= $POLKIT_MIN_VERSION)
|
||||
|
||||
GJS_VERSION=`$PKG_CONFIG --modversion gjs-internals-1.0`
|
||||
AC_DEFINE_UNQUOTED([GJS_VERSION], ["$GJS_VERSION"], [The version of GJS we're linking to])
|
||||
@ -97,8 +97,8 @@ GOBJECT_INTROSPECTION_CHECK([$GOBJECT_INTROSPECTION_MIN_VERSION])
|
||||
|
||||
saved_CFLAGS=$CFLAGS
|
||||
saved_LIBS=$LIBS
|
||||
CFLAGS=$MUTTER_PLUGIN_CFLAGS
|
||||
LIBS=$MUTTER_PLUGIN_LIBS
|
||||
CFLAGS=$GNOME_SHELL_CFLAGS
|
||||
LIBS=$GNOME_SHELL_LIBS
|
||||
# sn_startup_sequence_get_application_id, we can replace with a version check later
|
||||
AC_CHECK_FUNCS(JS_NewGlobalObject sn_startup_sequence_get_application_id)
|
||||
CFLAGS=$saved_CFLAGS
|
||||
@ -134,13 +134,10 @@ PKG_CHECK_MODULES(CALENDAR_SERVER, libecal-1.2 >= $LIBECAL_MIN_VERSION libedatas
|
||||
AC_SUBST(CALENDAR_SERVER_CFLAGS)
|
||||
AC_SUBST(CALENDAR_SERVER_LIBS)
|
||||
|
||||
MUTTER_BIN_DIR=`$PKG_CONFIG --variable=exec_prefix mutter-plugins`/bin
|
||||
# FIXME: metacity-plugins.pc should point directly to its .gir file
|
||||
MUTTER_LIB_DIR=`$PKG_CONFIG --variable=libdir mutter-plugins`
|
||||
MUTTER_PLUGIN_DIR=`$PKG_CONFIG --variable=plugindir mutter-plugins`
|
||||
AC_SUBST(MUTTER_BIN_DIR)
|
||||
AC_SUBST(MUTTER_LIB_DIR)
|
||||
AC_SUBST(MUTTER_PLUGIN_DIR)
|
||||
MUTTER_GIR_DIR=`$PKG_CONFIG --variable=girdir libmutter-wm`
|
||||
MUTTER_TYPELIB_DIR=`$PKG_CONFIG --variable=typelibdir libmutter-wm`
|
||||
AC_SUBST(MUTTER_GIR_DIR)
|
||||
AC_SUBST(MUTTER_TYPELIB_DIR)
|
||||
|
||||
GJS_CONSOLE=`$PKG_CONFIG --variable=gjs_console gjs-1.0`
|
||||
AC_SUBST(GJS_CONSOLE)
|
||||
@ -207,9 +204,6 @@ AC_ARG_ENABLE(dynamic-mozjs-hack,
|
||||
ENABLE_DYNAMIC_MOZJS_HACK=$enable_dynamic_mozjs_hack
|
||||
AC_SUBST(ENABLE_DYNAMIC_MOZJS_HACK)
|
||||
|
||||
AC_PATH_PROG(mutter, [mutter])
|
||||
AC_SUBST(mutter)
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
data/Makefile
|
||||
|
@ -10,17 +10,31 @@ noinst_PROGRAMS =
|
||||
-include $(INTROSPECTION_MAKEFILE)
|
||||
INTROSPECTION_GIRS =
|
||||
INTROSPECTION_SCANNER_ARGS = --warn-all --warn-error --add-include-path=$(srcdir)
|
||||
INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) --includedir=$(MUTTER_LIB_DIR)/mutter/
|
||||
INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) --includedir=$(MUTTER_TYPELIB_DIR)
|
||||
|
||||
typelibdir = $(pkglibdir)
|
||||
typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
|
||||
|
||||
CLEANFILES += $(gir_DATA) $(typelib_DATA)
|
||||
|
||||
generated_bin_scripts = gnome-shell-installed gnome-shell-jhbuild gnome-shell-extension-tool
|
||||
bin_SCRIPTS += gnome-shell $(generated_bin_scripts)
|
||||
bin_SCRIPTS += gnome-shell-extension-tool
|
||||
bin_PROGRAMS = gnome-shell-real
|
||||
|
||||
generated_script_substitutions = -e "s|@MUTTER_BIN_DIR[@]|$(MUTTER_BIN_DIR)|" \
|
||||
if USE_JHBUILD_WRAPPER_SCRIPT
|
||||
gnome_shell = gnome-shell-jhbuild
|
||||
bin_SCRIPTS += gnome-shell-jhbuild
|
||||
else
|
||||
gnome_shell = gnome-shell-real
|
||||
endif
|
||||
|
||||
noinst_DATA = gnome-shell
|
||||
gnome-shell: $(gnome_shell) Makefile
|
||||
cp $< $@.tmp && mv $@.tmp $@
|
||||
install-exec-hook:
|
||||
mv $(DESTDIR)$(bindir)/$(gnome_shell) $(DESTDIR)$(bindir)/gnome-shell
|
||||
|
||||
generated_script_substitutions = \
|
||||
-e "s|@bindir[@]|$(bindir)|" \
|
||||
-e "s|@datadir[@]|$(datadir)|" \
|
||||
-e "s|@libexecdir[@]|$(libexecdir)|" \
|
||||
-e "s|@libdir[@]|$(libdir)|" \
|
||||
@ -33,22 +47,11 @@ generated_script_substitutions = -e "s|@MUTTER_BIN_DIR[@]|$(MUTTER_BIN_DIR)|" \
|
||||
gnome-shell-jhbuild: gnome-shell-jhbuild.in Makefile
|
||||
$(AM_V_GEN) sed $(generated_script_substitutions) $< > $@.tmp && mv $@.tmp $@ && chmod a+x $@
|
||||
|
||||
gnome-shell-installed: gnome-shell-installed.in Makefile
|
||||
$(AM_V_GEN) sed $(generated_script_substitutions) $< > $@.tmp && mv $@.tmp $@ && chmod a+x $@
|
||||
|
||||
gnome-shell-extension-tool: gnome-shell-extension-tool.in Makefile
|
||||
$(AM_V_GEN) sed $(generated_script_substitutions) $< > $@.tmp && mv $@.tmp $@ && chmod a+x $@
|
||||
|
||||
if USE_JHBUILD_WRAPPER_SCRIPT
|
||||
gnome-shell: gnome-shell-jhbuild Makefile
|
||||
cp $< $@.tmp && mv $@.tmp $@
|
||||
else
|
||||
gnome-shell: gnome-shell-installed Makefile
|
||||
cp $< $@.tmp && mv $@.tmp $@
|
||||
endif
|
||||
|
||||
CLEANFILES += gnome-shell $(generated_bin_scripts)
|
||||
EXTRA_DIST += $(generated_bin_scripts:=.in)
|
||||
CLEANFILES += gnome-shell $(bin_SCRIPTS)
|
||||
EXTRA_DIST += $(bin_SCRIPTS:=.in)
|
||||
|
||||
include Makefile-gdmuser.am
|
||||
include Makefile-st.am
|
||||
@ -57,17 +60,17 @@ include Makefile-gvc.am
|
||||
include Makefile-calendar-server.am
|
||||
|
||||
gnome_shell_cflags = \
|
||||
$(MUTTER_PLUGIN_CFLAGS) \
|
||||
$(LIBGNOMEUI_CFLAGS) \
|
||||
$(GNOME_SHELL_CFLAGS) \
|
||||
-I$(srcdir)/tray \
|
||||
-DVERSION=\"$(VERSION)\" \
|
||||
-DLOCALEDIR=\"$(datadir)/locale\" \
|
||||
-DGNOME_SHELL_LIBEXECDIR=\"$(libexecdir)\" \
|
||||
-DGNOME_SHELL_DATADIR=\"$(pkgdatadir)\" \
|
||||
-DGNOME_SHELL_PKGLIBDIR=\"$(pkglibdir)\" \
|
||||
-DJSDIR=\"$(pkgdatadir)/js\"
|
||||
|
||||
plugindir = $(MUTTER_PLUGIN_DIR)
|
||||
plugin_LTLIBRARIES = libgnome-shell.la
|
||||
privlibdir = $(pkglibdir)
|
||||
privlib_LTLIBRARIES = libgnome-shell.la
|
||||
|
||||
shell_built_sources = \
|
||||
shell-marshal.h \
|
||||
@ -134,6 +137,11 @@ libgnome_shell_la_SOURCES = \
|
||||
libgnome_shell_la_gir_sources = \
|
||||
$(filter-out %-private.h $(shell_recorder_non_gir_sources), $(shell_public_headers_h) $(libgnome_shell_la_SOURCES))
|
||||
|
||||
gnome_shell_real_SOURCES = \
|
||||
main.c
|
||||
gnome_shell_real_CPPFLAGS = $(gnome_shell_cflags)
|
||||
gnome_shell_real_LDADD = -lgnome-shell
|
||||
|
||||
########################################
|
||||
|
||||
shell_recorder_sources = \
|
||||
@ -232,11 +240,10 @@ shell-enum-types.c: shell-enum-types.c.in stamp-shell-enum-types.h
|
||||
rm -f $@.tmp
|
||||
EXTRA_DIST += shell-enum-types.c.in
|
||||
|
||||
libgnome_shell_la_LDFLAGS = -avoid-version -module
|
||||
libgnome_shell_la_LIBADD = \
|
||||
libgnome_shell_la_LDFLAGS = -avoid-version
|
||||
libgnome_shell_la_LIBADD = \
|
||||
-lm \
|
||||
$(MUTTER_PLUGIN_LIBS) \
|
||||
$(LIBGNOMEUI_LIBS) \
|
||||
$(GNOME_SHELL_LIBS) \
|
||||
$(BLUETOOTH_LIBS) \
|
||||
libst-1.0.la \
|
||||
libgdmuser-1.0.la \
|
||||
@ -244,7 +251,7 @@ libgnome_shell_la_LIBADD = \
|
||||
libgvc.la \
|
||||
$(NULL)
|
||||
|
||||
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags) $(LIBECAL_CFLAGS)
|
||||
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
|
||||
|
||||
Shell-0.1.gir: libgnome-shell.la St-1.0.gir
|
||||
Shell_0_1_gir_INCLUDES = Clutter-1.0 ClutterX11-1.0 Meta-2.91 TelepathyGLib-0.12
|
||||
@ -252,9 +259,7 @@ Shell_0_1_gir_CFLAGS = $(libgnome_shell_la_CPPFLAGS) -I $(srcdir)
|
||||
Shell_0_1_gir_LIBS = libgnome-shell.la
|
||||
Shell_0_1_gir_FILES = $(addprefix $(srcdir)/,$(libgnome_shell_la_gir_sources))
|
||||
Shell_0_1_gir_SCANNERFLAGS = --include-uninstalled=$(builddir)/St-1.0.gir \
|
||||
--add-include-path=$(MUTTER_LIB_DIR)/mutter/ \
|
||||
--program=mutter \
|
||||
--program-arg=--mutter-plugins=`pwd`/libgnome-shell.la
|
||||
--add-include-path=$(MUTTER_GIR_DIR)
|
||||
INTROSPECTION_GIRS += Shell-0.1.gir
|
||||
|
||||
St-1.0.gir: libst-1.0.la
|
||||
|
@ -1,41 +0,0 @@
|
||||
#!/bin/bash
|
||||
# gnome-shell is a plugin for mutter; start mutter with the right
|
||||
# options.
|
||||
|
||||
# About the value of NO_GAIL and NO_AT_BRIDGE: If a11y is enabled,
|
||||
# gtk_init() will normally load gail and at-bridge. But we don't
|
||||
# want at-bridge to be loaded until after clutter is initialized
|
||||
# (which mutter does after initializing gtk) and we don't want
|
||||
# gail to be loaded at all. So set these flags. shell_a11y_init()
|
||||
# will clear them so they don't get passed to gnome-shell's
|
||||
# children.
|
||||
export NO_GAIL=1
|
||||
export NO_AT_BRIDGE=1
|
||||
|
||||
# FIXME - Add gjs API to set this stuff and don't depend on the
|
||||
# environment. These propagate to child processes.
|
||||
export GJS_DEBUG_OUTPUT='stderr'
|
||||
# By default only let gjs show errors and things that are explicitly
|
||||
# logged via log() from javascript
|
||||
export GJS_DEBUG_TOPICS='JS ERROR;JS LOG'
|
||||
|
||||
if test -z "$MUTTER_PLUGINS"; then
|
||||
MUTTER_PLUGINS=libgnome-shell
|
||||
fi
|
||||
|
||||
# Work around Ubuntu xulrunner bug,
|
||||
# http://bugzilla.gnome.org/show_bug.cgi?id=573413
|
||||
if test x@ENABLE_DYNAMIC_MOZJS_HACK@ = xyes; then
|
||||
sdkdir=$(pkg-config --variable=sdkdir mozilla-js)
|
||||
if test -n "${sdkdir}"; then
|
||||
mozjs_libdir=$(echo "$sdkdir" | sed -e s,'-\(sdk\|devel\)',,)
|
||||
if test -n "$LD_LIBRARY_PATH"; then
|
||||
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$mozjs_libdir
|
||||
else
|
||||
LD_LIBRARY_PATH=$mozjs_libdir
|
||||
fi
|
||||
export LD_LIBRARY_PATH
|
||||
fi
|
||||
fi
|
||||
|
||||
exec mutter --mutter-plugins=$MUTTER_PLUGINS "$@"
|
@ -143,17 +143,15 @@ def start_dconf_await_service():
|
||||
loop.run()
|
||||
|
||||
def start_shell(perf_output=None):
|
||||
bin_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
if os.path.exists(os.path.join(bin_dir, 'gnome-shell-jhbuild.in')):
|
||||
self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
if os.path.exists(os.path.join(self_dir, 'gnome-shell-jhbuild.in')):
|
||||
running_from_source_tree = True
|
||||
top_dir = os.path.dirname(bin_dir)
|
||||
plugin = os.path.join(top_dir, 'src', 'libgnome-shell.la')
|
||||
top_dir = os.path.dirname(self_dir)
|
||||
typelib_dir = os.path.join(top_dir, "src")
|
||||
js_dir = os.path.join(top_dir, "js")
|
||||
data_dir = os.path.join(top_dir, "data")
|
||||
else:
|
||||
running_from_source_tree = False
|
||||
plugin = 'libgnome-shell'
|
||||
js_dir = os.path.join('@pkgdatadir@', 'js')
|
||||
|
||||
# Set up environment
|
||||
@ -166,13 +164,13 @@ def start_shell(perf_output=None):
|
||||
# below. Otherwise it's just a bad reimplementation of "jhbuild
|
||||
# run". See bug #642084
|
||||
env.update({'GNOME_SHELL_JS' : js_dir,
|
||||
'PATH' : '@MUTTER_BIN_DIR@:' + os.environ.get('PATH', ''),
|
||||
'PATH' : '@bindir@:' + os.environ.get('PATH', ''),
|
||||
'XDG_CONFIG_DIRS' : '@sysconfdir@/xdg:' + (os.environ.get('XDG_CONFIG_DIRS') or '/etc/xdg'),
|
||||
'XDG_DATA_DIRS' : '@datadir@:' + (os.environ.get('XDG_DATA_DIRS') or '/usr/local/share:/usr/share')})
|
||||
if running_from_source_tree:
|
||||
if os.environ.has_key('GI_TYPELIB_PATH'):
|
||||
typelib_dir = typelib_dir + ":" + os.environ.get('GI_TYPELIB_PATH')
|
||||
env.update({'GNOME_SHELL_BINDIR' : bin_dir,
|
||||
env.update({'GNOME_SHELL_BINDIR' : self_dir,
|
||||
'GNOME_SHELL_DATADIR' : data_dir,
|
||||
'GI_TYPELIB_PATH' : typelib_dir,
|
||||
'GSETTINGS_SCHEMA_DIR' : data_dir })
|
||||
@ -191,15 +189,14 @@ def start_shell(perf_output=None):
|
||||
if perf_output is not None:
|
||||
env['SHELL_PERF_OUTPUT'] = perf_output
|
||||
|
||||
args = []
|
||||
if options.debug:
|
||||
debug_command = options.debug_command.split()
|
||||
args = list(debug_command)
|
||||
else:
|
||||
args = []
|
||||
if running_from_source_tree:
|
||||
args += [os.path.join(top_dir, 'libtool'), '--mode=execute']
|
||||
args += debug_command
|
||||
|
||||
if running_from_source_tree:
|
||||
env['MUTTER_PLUGINS'] = plugin
|
||||
args.append(os.path.join(bin_dir, 'gnome-shell-installed'))
|
||||
args.append(os.path.join(self_dir, 'gnome-shell-real'))
|
||||
if options.replace:
|
||||
args.append('--replace')
|
||||
if options.sync:
|
||||
@ -427,9 +424,9 @@ def run_performance_test():
|
||||
}
|
||||
|
||||
# Add the Git revision if available
|
||||
bin_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
if os.path.exists(os.path.join(bin_dir, 'gnome-shell.in')):
|
||||
top_dir = os.path.dirname(bin_dir)
|
||||
self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
if os.path.exists(os.path.join(self_dir, 'gnome-shell-jhbuild.in')):
|
||||
top_dir = os.path.dirname(self_dir)
|
||||
git_dir = os.path.join(top_dir, '.git')
|
||||
if os.path.exists(git_dir):
|
||||
env = dict(os.environ)
|
||||
|
@ -27,19 +27,9 @@
|
||||
|
||||
#include <meta-plugin.h>
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gjs/gjs.h>
|
||||
#include <girepository.h>
|
||||
#include <gmodule.h>
|
||||
#ifdef HAVE_MALLINFO
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -51,16 +41,10 @@
|
||||
#include "shell-global-private.h"
|
||||
#include "shell-perf-log.h"
|
||||
#include "shell-wm-private.h"
|
||||
#include "st.h"
|
||||
#include "shell-a11y.h"
|
||||
|
||||
#define SHELL_DBUS_SERVICE "org.gnome.Shell"
|
||||
#define MAGNIFIER_DBUS_SERVICE "org.gnome.Magnifier"
|
||||
|
||||
static void gnome_shell_plugin_dispose (GObject *object);
|
||||
static void gnome_shell_plugin_finalize (GObject *object);
|
||||
|
||||
static void gnome_shell_plugin_early_initialize (MetaPlugin *plugin);
|
||||
static void gnome_shell_plugin_start (MetaPlugin *plugin);
|
||||
static void gnome_shell_plugin_minimize (MetaPlugin *plugin,
|
||||
MetaWindowActor *actor);
|
||||
@ -110,7 +94,6 @@ struct _GnomeShellPlugin
|
||||
{
|
||||
MetaPlugin parent;
|
||||
|
||||
GjsContext *gjs_context;
|
||||
Atom panel_action;
|
||||
Atom panel_action_run_dialog;
|
||||
Atom panel_action_main_menu;
|
||||
@ -127,11 +110,9 @@ struct _GnomeShellPluginClass
|
||||
MetaPluginClass parent_class;
|
||||
};
|
||||
|
||||
/*
|
||||
* Create the plugin struct; function pointers initialized in
|
||||
* g_module_check_init().
|
||||
*/
|
||||
META_PLUGIN_DECLARE(GnomeShellPlugin, gnome_shell_plugin);
|
||||
GType gnome_shell_plugin_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (GnomeShellPlugin, gnome_shell_plugin, META_TYPE_PLUGIN)
|
||||
|
||||
static void
|
||||
gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
|
||||
@ -142,7 +123,6 @@ gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
|
||||
gobject_class->dispose = gnome_shell_plugin_dispose;
|
||||
gobject_class->finalize = gnome_shell_plugin_finalize;
|
||||
|
||||
plugin_class->early_initialize = gnome_shell_plugin_early_initialize;
|
||||
plugin_class->start = gnome_shell_plugin_start;
|
||||
plugin_class->map = gnome_shell_plugin_map;
|
||||
plugin_class->minimize = gnome_shell_plugin_minimize;
|
||||
@ -162,328 +142,6 @@ gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
|
||||
static void
|
||||
gnome_shell_plugin_init (GnomeShellPlugin *shell_plugin)
|
||||
{
|
||||
meta_prefs_override_preference_location ("/apps/mutter/general/attach_modal_dialogs",
|
||||
"/desktop/gnome/shell/windows/attach_modal_dialogs");
|
||||
meta_prefs_override_preference_location ("/apps/metacity/general/button_layout",
|
||||
"/desktop/gnome/shell/windows/button_layout");
|
||||
meta_prefs_override_preference_location ("/apps/metacity/general/edge_tiling",
|
||||
"/desktop/gnome/shell/windows/edge_tiling");
|
||||
meta_prefs_override_preference_location ("/apps/metacity/general/theme",
|
||||
"/desktop/gnome/shell/windows/theme");
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
clutter_set_font_flags (clutter_get_font_flags () & ~CLUTTER_FONT_MIPMAPPING);
|
||||
|
||||
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);
|
||||
|
||||
/* 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
|
||||
malloc_statistics_callback (ShellPerfLog *perf_log,
|
||||
gpointer data)
|
||||
{
|
||||
#ifdef HAVE_MALLINFO
|
||||
struct mallinfo info = mallinfo ();
|
||||
|
||||
shell_perf_log_update_statistic_i (perf_log,
|
||||
"malloc.arenaSize",
|
||||
info.arena);
|
||||
shell_perf_log_update_statistic_i (perf_log,
|
||||
"malloc.mmapSize",
|
||||
info.hblkhd);
|
||||
shell_perf_log_update_statistic_i (perf_log,
|
||||
"malloc.usedSize",
|
||||
info.uordblks);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
add_statistics (GnomeShellPlugin *shell_plugin)
|
||||
{
|
||||
ShellPerfLog *perf_log = shell_perf_log_get_default ();
|
||||
|
||||
/* For probably historical reasons, mallinfo() defines the returned values,
|
||||
* even those in bytes as int, not size_t. We're determined not to use
|
||||
* more than 2G of malloc'ed memory, so are OK with that.
|
||||
*/
|
||||
shell_perf_log_define_statistic (perf_log,
|
||||
"malloc.arenaSize",
|
||||
"Amount of memory allocated by malloc() with brk(), in bytes",
|
||||
"i");
|
||||
shell_perf_log_define_statistic (perf_log,
|
||||
"malloc.mmapSize",
|
||||
"Amount of memory allocated by malloc() with mmap(), in bytes",
|
||||
"i");
|
||||
shell_perf_log_define_statistic (perf_log,
|
||||
"malloc.usedSize",
|
||||
"Amount of malloc'ed memory currently in use",
|
||||
"i");
|
||||
|
||||
shell_perf_log_add_statistics_callback (perf_log,
|
||||
malloc_statistics_callback,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/* 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
|
||||
muted_log_handler (const char *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const char *message,
|
||||
gpointer data)
|
||||
{
|
||||
/* Intentionally empty to discard message */
|
||||
}
|
||||
|
||||
static void
|
||||
gnome_shell_plugin_early_initialize (MetaPlugin *plugin)
|
||||
{
|
||||
GError *error = NULL;
|
||||
DBusGConnection *session;
|
||||
DBusGProxy *bus;
|
||||
guint32 request_name_result;
|
||||
|
||||
/** TODO:
|
||||
* In the future we should use GDBus for this. However, in
|
||||
* order to do that, we need to port all of the JavaScript
|
||||
* code. Otherwise, the name will be claimed on the wrong
|
||||
* connection.
|
||||
*/
|
||||
session = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
|
||||
|
||||
bus = dbus_g_proxy_new_for_name (session,
|
||||
DBUS_SERVICE_DBUS,
|
||||
DBUS_PATH_DBUS,
|
||||
DBUS_INTERFACE_DBUS);
|
||||
|
||||
if (!dbus_g_proxy_call (bus, "RequestName", &error,
|
||||
G_TYPE_STRING, SHELL_DBUS_SERVICE,
|
||||
G_TYPE_UINT, 0,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_UINT, &request_name_result,
|
||||
G_TYPE_INVALID))
|
||||
{
|
||||
g_print ("failed to acquire org.gnome.Shell: %s\n", error->message);
|
||||
/* If we somehow got started again, it's not an error to be running
|
||||
* already. So just exit 0.
|
||||
*/
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* Also grab org.gnome.Panel to replace any existing panel process,
|
||||
* unless a special environment variable is passed. The environment
|
||||
* variable is used by the gnome-shell (no --replace) launcher in
|
||||
* Xephyr */
|
||||
if (!dbus_g_proxy_call (bus, "RequestName", &error, G_TYPE_STRING,
|
||||
"org.gnome.Panel", G_TYPE_UINT,
|
||||
DBUS_NAME_FLAG_REPLACE_EXISTING | DBUS_NAME_FLAG_DO_NOT_QUEUE,
|
||||
G_TYPE_INVALID, G_TYPE_UINT,
|
||||
&request_name_result, G_TYPE_INVALID))
|
||||
{
|
||||
g_print ("failed to acquire org.gnome.Panel: %s\n", error->message);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* ...and the org.gnome.Magnifier service.
|
||||
*/
|
||||
if (!dbus_g_proxy_call (bus, "RequestName", &error,
|
||||
G_TYPE_STRING, MAGNIFIER_DBUS_SERVICE,
|
||||
G_TYPE_UINT, 0,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_UINT, &request_name_result,
|
||||
G_TYPE_INVALID))
|
||||
{
|
||||
g_print ("failed to acquire %s: %s\n", MAGNIFIER_DBUS_SERVICE, error->message);
|
||||
/* Failing to acquire the magnifer service is not fatal. Log the error,
|
||||
* but keep going. */
|
||||
}
|
||||
|
||||
/* ...and the org.freedesktop.Notifications service.
|
||||
*/
|
||||
if (!dbus_g_proxy_call (bus, "RequestName", &error,
|
||||
G_TYPE_STRING, "org.freedesktop.Notifications",
|
||||
G_TYPE_UINT, DBUS_NAME_FLAG_REPLACE_EXISTING | DBUS_NAME_FLAG_DO_NOT_QUEUE,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_UINT, &request_name_result,
|
||||
G_TYPE_INVALID))
|
||||
{
|
||||
g_print ("failed to acquire org.freedesktop.Notifications: %s\n", error->message);
|
||||
}
|
||||
|
||||
g_object_unref (bus);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -493,32 +151,10 @@ gnome_shell_plugin_start (MetaPlugin *plugin)
|
||||
MetaScreen *screen;
|
||||
MetaDisplay *display;
|
||||
Display *xdisplay;
|
||||
GtkSettings *settings;
|
||||
GError *error = NULL;
|
||||
int status;
|
||||
const char *shell_js;
|
||||
char **search_path;
|
||||
const char *glx_extensions;
|
||||
|
||||
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
|
||||
shell_a11y_init ();
|
||||
|
||||
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);
|
||||
|
||||
gdk_event_handler_set (gnome_shell_gdk_event_handler, plugin, NULL);
|
||||
GjsContext *gjs_context;
|
||||
|
||||
screen = meta_plugin_get_screen (plugin);
|
||||
display = meta_screen_get_display (screen);
|
||||
@ -538,40 +174,12 @@ gnome_shell_plugin_start (MetaPlugin *plugin)
|
||||
"GL buffer swap complete event received (with timestamp of completion)",
|
||||
"x");
|
||||
|
||||
#if HAVE_BLUETOOTH
|
||||
g_irepository_prepend_search_path (BLUETOOTH_DIR);
|
||||
#endif
|
||||
|
||||
g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
|
||||
|
||||
shell_js = g_getenv("GNOME_SHELL_JS");
|
||||
if (!shell_js)
|
||||
shell_js = JSDIR;
|
||||
|
||||
search_path = g_strsplit(shell_js, ":", -1);
|
||||
shell_plugin->gjs_context = g_object_new (GJS_TYPE_CONTEXT,
|
||||
"search-path", search_path,
|
||||
"js-version", "1.8",
|
||||
NULL);
|
||||
g_strfreev(search_path);
|
||||
|
||||
/* Disable debug spew from various libraries */
|
||||
g_log_set_handler ("Gvc", G_LOG_LEVEL_DEBUG,
|
||||
muted_log_handler, NULL);
|
||||
g_log_set_handler ("GdmUser", G_LOG_LEVEL_DEBUG,
|
||||
muted_log_handler, NULL);
|
||||
g_log_set_handler ("Bluetooth", G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_MESSAGE,
|
||||
muted_log_handler, NULL);
|
||||
|
||||
/* Initialize the global object here. */
|
||||
shell_plugin->global = shell_global_get ();
|
||||
_shell_global_set_plugin (shell_plugin->global, META_PLUGIN (shell_plugin));
|
||||
|
||||
_shell_global_set_plugin (shell_plugin->global, META_PLUGIN(shell_plugin));
|
||||
_shell_global_set_gjs_context (shell_plugin->global, shell_plugin->gjs_context);
|
||||
gjs_context = _shell_global_get_gjs_context (shell_plugin->global);
|
||||
|
||||
add_statistics (shell_plugin);
|
||||
|
||||
if (!gjs_context_eval (shell_plugin->gjs_context,
|
||||
if (!gjs_context_eval (gjs_context,
|
||||
"const Main = imports.ui.main; Main.start();",
|
||||
-1,
|
||||
"<main>",
|
||||
@ -752,17 +360,3 @@ MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin)
|
||||
|
||||
return &info;
|
||||
}
|
||||
|
||||
#if HAVE_BLUETOOTH
|
||||
/* HACK:
|
||||
Add a non-static function that calls into libgnome-bluetooth-applet.so,
|
||||
to avoid the linker being too smart and removing the dependency.
|
||||
This function is never actually called.
|
||||
*/
|
||||
extern GType bluetooth_applet_get_type(void);
|
||||
void _shell_link_to_bluetooth(void);
|
||||
|
||||
void _shell_link_to_bluetooth(void) {
|
||||
bluetooth_applet_get_type();
|
||||
}
|
||||
#endif
|
||||
|
460
src/main.c
Normal file
460
src/main.c
Normal file
@ -0,0 +1,460 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_MALLINFO
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <girepository.h>
|
||||
#include <main.h>
|
||||
#include <meta-plugin.h>
|
||||
#include <prefs.h>
|
||||
|
||||
#include "shell-a11y.h"
|
||||
#include "shell-global.h"
|
||||
#include "shell-perf-log.h"
|
||||
#include "st.h"
|
||||
|
||||
extern GType gnome_shell_plugin_get_type (void);
|
||||
|
||||
#define SHELL_DBUS_SERVICE "org.gnome.Shell"
|
||||
#define MAGNIFIER_DBUS_SERVICE "org.gnome.Magnifier"
|
||||
|
||||
static void
|
||||
shell_dbus_init (void)
|
||||
{
|
||||
GError *error = NULL;
|
||||
DBusGConnection *session;
|
||||
DBusGProxy *bus;
|
||||
guint32 request_name_result;
|
||||
|
||||
/** TODO:
|
||||
* In the future we should use GDBus for this. However, in
|
||||
* order to do that, we need to port all of the JavaScript
|
||||
* code. Otherwise, the name will be claimed on the wrong
|
||||
* connection.
|
||||
*/
|
||||
session = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
|
||||
|
||||
bus = dbus_g_proxy_new_for_name (session,
|
||||
DBUS_SERVICE_DBUS,
|
||||
DBUS_PATH_DBUS,
|
||||
DBUS_INTERFACE_DBUS);
|
||||
|
||||
if (!dbus_g_proxy_call (bus, "RequestName", &error,
|
||||
G_TYPE_STRING, SHELL_DBUS_SERVICE,
|
||||
G_TYPE_UINT, 0,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_UINT, &request_name_result,
|
||||
G_TYPE_INVALID))
|
||||
{
|
||||
g_print ("failed to acquire org.gnome.Shell: %s\n", error->message);
|
||||
/* If we somehow got started again, it's not an error to be running
|
||||
* already. So just exit 0.
|
||||
*/
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* Also grab org.gnome.Panel to replace any existing panel process,
|
||||
* unless a special environment variable is passed. The environment
|
||||
* variable is used by the gnome-shell (no --replace) launcher in
|
||||
* Xephyr */
|
||||
if (!dbus_g_proxy_call (bus, "RequestName", &error, G_TYPE_STRING,
|
||||
"org.gnome.Panel", G_TYPE_UINT,
|
||||
DBUS_NAME_FLAG_REPLACE_EXISTING | DBUS_NAME_FLAG_DO_NOT_QUEUE,
|
||||
G_TYPE_INVALID, G_TYPE_UINT,
|
||||
&request_name_result, G_TYPE_INVALID))
|
||||
{
|
||||
g_print ("failed to acquire org.gnome.Panel: %s\n", error->message);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* ...and the org.gnome.Magnifier service.
|
||||
*/
|
||||
if (!dbus_g_proxy_call (bus, "RequestName", &error,
|
||||
G_TYPE_STRING, MAGNIFIER_DBUS_SERVICE,
|
||||
G_TYPE_UINT, 0,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_UINT, &request_name_result,
|
||||
G_TYPE_INVALID))
|
||||
{
|
||||
g_print ("failed to acquire %s: %s\n", MAGNIFIER_DBUS_SERVICE, error->message);
|
||||
/* Failing to acquire the magnifer service is not fatal. Log the error,
|
||||
* but keep going. */
|
||||
}
|
||||
|
||||
/* ...and the org.freedesktop.Notifications service.
|
||||
*/
|
||||
if (!dbus_g_proxy_call (bus, "RequestName", &error,
|
||||
G_TYPE_STRING, "org.freedesktop.Notifications",
|
||||
G_TYPE_UINT, DBUS_NAME_FLAG_REPLACE_EXISTING | DBUS_NAME_FLAG_DO_NOT_QUEUE,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_UINT, &request_name_result,
|
||||
G_TYPE_INVALID))
|
||||
{
|
||||
g_print ("failed to acquire org.freedesktop.Notifications: %s\n", error->message);
|
||||
}
|
||||
|
||||
g_object_unref (bus);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
clutter_set_font_flags (clutter_get_font_flags () & ~CLUTTER_FONT_MIPMAPPING);
|
||||
|
||||
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
|
||||
shell_prefs_init (void)
|
||||
{
|
||||
meta_prefs_override_preference_location ("/apps/mutter/general/attach_modal_dialogs",
|
||||
"/desktop/gnome/shell/windows/attach_modal_dialogs");
|
||||
meta_prefs_override_preference_location ("/apps/metacity/general/button_layout",
|
||||
"/desktop/gnome/shell/windows/button_layout");
|
||||
meta_prefs_override_preference_location ("/apps/metacity/general/edge_tiling",
|
||||
"/desktop/gnome/shell/windows/edge_tiling");
|
||||
meta_prefs_override_preference_location ("/apps/metacity/general/theme",
|
||||
"/desktop/gnome/shell/windows/theme");
|
||||
}
|
||||
|
||||
/* 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
|
||||
malloc_statistics_callback (ShellPerfLog *perf_log,
|
||||
gpointer data)
|
||||
{
|
||||
#ifdef HAVE_MALLINFO
|
||||
struct mallinfo info = mallinfo ();
|
||||
|
||||
shell_perf_log_update_statistic_i (perf_log,
|
||||
"malloc.arenaSize",
|
||||
info.arena);
|
||||
shell_perf_log_update_statistic_i (perf_log,
|
||||
"malloc.mmapSize",
|
||||
info.hblkhd);
|
||||
shell_perf_log_update_statistic_i (perf_log,
|
||||
"malloc.usedSize",
|
||||
info.uordblks);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
shell_perf_log_init (void)
|
||||
{
|
||||
ShellPerfLog *perf_log = shell_perf_log_get_default ();
|
||||
|
||||
/* For probably historical reasons, mallinfo() defines the returned values,
|
||||
* even those in bytes as int, not size_t. We're determined not to use
|
||||
* more than 2G of malloc'ed memory, so are OK with that.
|
||||
*/
|
||||
shell_perf_log_define_statistic (perf_log,
|
||||
"malloc.arenaSize",
|
||||
"Amount of memory allocated by malloc() with brk(), in bytes",
|
||||
"i");
|
||||
shell_perf_log_define_statistic (perf_log,
|
||||
"malloc.mmapSize",
|
||||
"Amount of memory allocated by malloc() with mmap(), in bytes",
|
||||
"i");
|
||||
shell_perf_log_define_statistic (perf_log,
|
||||
"malloc.usedSize",
|
||||
"Amount of malloc'ed memory currently in use",
|
||||
"i");
|
||||
|
||||
shell_perf_log_add_statistics_callback (perf_log,
|
||||
malloc_statistics_callback,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
muted_log_handler (const char *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const char *message,
|
||||
gpointer data)
|
||||
{
|
||||
/* Intentionally empty to discard message */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
print_version (const gchar *option_name,
|
||||
const gchar *value,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
g_print ("GNOME Shell %s\n", VERSION);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
GOptionEntry gnome_shell_options[] = {
|
||||
{
|
||||
"version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
|
||||
print_version,
|
||||
N_("Print version"),
|
||||
NULL
|
||||
},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GOptionContext *ctx;
|
||||
GError *error = NULL;
|
||||
|
||||
g_type_init ();
|
||||
|
||||
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
|
||||
ctx = meta_get_option_context ();
|
||||
g_option_context_add_main_entries (ctx, gnome_shell_options, GETTEXT_PACKAGE);
|
||||
if (!g_option_context_parse (ctx, &argc, &argv, &error))
|
||||
{
|
||||
g_printerr ("%s: %s\n", argv[0], error->message);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
meta_plugin_type_register (gnome_shell_plugin_get_type ());
|
||||
|
||||
/* Prevent meta_init() from causing gtk to load gail and at-bridge */
|
||||
g_setenv ("NO_GAIL", "1", TRUE);
|
||||
g_setenv ("NO_AT_BRIDGE", "1", TRUE);
|
||||
meta_init ();
|
||||
g_unsetenv ("NO_GAIL");
|
||||
g_unsetenv ("NO_AT_BRIDGE");
|
||||
|
||||
/* FIXME: Add gjs API to set this stuff and don't depend on the
|
||||
* environment. These propagate to child processes.
|
||||
*/
|
||||
g_setenv ("GJS_DEBUG_OUTPUT", "stderr", TRUE);
|
||||
g_setenv ("GJS_DEBUG_TOPICS", "JS ERROR;JS LOG", TRUE);
|
||||
|
||||
shell_dbus_init ();
|
||||
shell_a11y_init ();
|
||||
shell_fonts_init ();
|
||||
shell_perf_log_init ();
|
||||
shell_prefs_init ();
|
||||
|
||||
gdk_event_handler_set (gnome_shell_gdk_event_handler, NULL, NULL);
|
||||
|
||||
g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
|
||||
#if HAVE_BLUETOOTH
|
||||
g_irepository_prepend_search_path (BLUETOOTH_DIR);
|
||||
#endif
|
||||
|
||||
/* Disable debug spew from various libraries */
|
||||
g_log_set_handler ("Gvc", G_LOG_LEVEL_DEBUG,
|
||||
muted_log_handler, NULL);
|
||||
g_log_set_handler ("GdmUser", G_LOG_LEVEL_DEBUG,
|
||||
muted_log_handler, NULL);
|
||||
g_log_set_handler ("Bluetooth", G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_MESSAGE,
|
||||
muted_log_handler, NULL);
|
||||
|
||||
/* Initialize the global object */
|
||||
shell_global_get ();
|
||||
|
||||
return meta_run ();
|
||||
}
|
@ -134,9 +134,6 @@ shell_a11y_init (void)
|
||||
{
|
||||
char *bridge_path = NULL;
|
||||
|
||||
g_unsetenv ("NO_AT_BRIDGE");
|
||||
g_unsetenv ("NO_GAIL");
|
||||
|
||||
if (!should_enable_a11y ())
|
||||
return;
|
||||
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
void _shell_global_set_plugin (ShellGlobal *global,
|
||||
MetaPlugin *plugin);
|
||||
void _shell_global_set_gjs_context (ShellGlobal *global,
|
||||
GjsContext *context);
|
||||
|
||||
GjsContext *_shell_global_get_gjs_context (ShellGlobal *global);
|
||||
|
||||
gboolean _shell_global_check_xdnd_event (ShellGlobal *global,
|
||||
XEvent *xev);
|
||||
|
@ -203,7 +203,8 @@ static void
|
||||
shell_global_init (ShellGlobal *global)
|
||||
{
|
||||
const char *datadir = g_getenv ("GNOME_SHELL_DATADIR");
|
||||
char *imagedir;
|
||||
const char *shell_js = g_getenv("GNOME_SHELL_JS");
|
||||
char *imagedir, **search_path;
|
||||
|
||||
if (!datadir)
|
||||
datadir = GNOME_SHELL_DATADIR;
|
||||
@ -242,6 +243,15 @@ shell_global_init (ShellGlobal *global)
|
||||
ca_context_create (&global->sound_context);
|
||||
ca_context_change_props (global->sound_context, CA_PROP_APPLICATION_NAME, PACKAGE_NAME, CA_PROP_APPLICATION_ID, "org.gnome.Shell", NULL);
|
||||
ca_context_open (global->sound_context);
|
||||
|
||||
if (!shell_js)
|
||||
shell_js = JSDIR;
|
||||
search_path = g_strsplit (shell_js, ":", -1);
|
||||
global->js_context = g_object_new (GJS_TYPE_CONTEXT,
|
||||
"search-path", search_path,
|
||||
"js-version", "1.8",
|
||||
NULL);
|
||||
g_strfreev (search_path);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -791,11 +801,10 @@ _shell_global_set_plugin (ShellGlobal *global,
|
||||
global->focus_manager = st_focus_manager_get_for_stage (CLUTTER_STAGE (stage));
|
||||
}
|
||||
|
||||
void
|
||||
_shell_global_set_gjs_context (ShellGlobal *global,
|
||||
GjsContext *context)
|
||||
GjsContext *
|
||||
_shell_global_get_gjs_context (ShellGlobal *global)
|
||||
{
|
||||
global->js_context = context;
|
||||
return global->js_context;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,7 +27,7 @@ EXTRA_DIST += $(TEST_MISC)
|
||||
|
||||
run-test.sh: run-test.sh.in
|
||||
$(AM_V_GEN) sed \
|
||||
-e "s|@MUTTER_LIB_DIR[@]|$(MUTTER_LIB_DIR)|" \
|
||||
-e "s|@MUTTER_TYPELIB_DIR[@]|$(MUTTER_TYPELIB_DIR)|" \
|
||||
-e "s|@srcdir[@]|$(srcdir)|" \
|
||||
$< > $@ && chmod a+x $@
|
||||
|
||||
|
2
tests/run-test.sh.in
Normal file → Executable file
2
tests/run-test.sh.in
Normal file → Executable file
@ -30,7 +30,7 @@ builddir=`cd $builddir && pwd`
|
||||
srcdir=$builddir/@srcdir@
|
||||
srcdir=`cd $srcdir && pwd`
|
||||
|
||||
GI_TYPELIB_PATH="@MUTTER_LIB_DIR@/mutter:$builddir/../src"
|
||||
GI_TYPELIB_PATH="@MUTTER_TYPELIB_DIR@:$builddir/../src"
|
||||
GJS_PATH="$srcdir:$srcdir/../js"
|
||||
GJS_DEBUG_OUTPUT=stderr
|
||||
$verbose || GJS_DEBUG_TOPICS="JS ERROR;JS LOG"
|
||||
|
Loading…
Reference in New Issue
Block a user