gnome-shell/src/gnome-shell-plugin.c
Owen W. Taylor 98a093a279 Remove icon and menu from titlebar
To avoid visual duplication with the application menu, eliminate
the window menu button. (The window menu can still be accessed by
right-clicking on the title bar, or Alt-right-clicking anywhere on the
window.)

This is implemented using the new Mutter facility for GConf key
redirection; we add separate key for 'button_layout' with a default
that omits the menu button.

https://bugzilla.gnome.org/show_bug.cgi?id=591390
2010-04-13 13:58:42 -04:00

340 lines
12 KiB
C

/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (c) 2008 Red Hat, Inc.
* Copyright (c) 2008 Intel Corp.
*
* Based on plugin skeleton by:
* Author: Tomas Frydrych <tf@linux.intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "config.h"
#define MUTTER_BUILDING_PLUGIN 1
#include <mutter-plugin.h>
#include <glib/gi18n-lib.h>
#include <clutter/clutter.h>
#include <clutter/x11/clutter-x11.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gjs/gjs.h>
#include <girepository.h>
#include <gmodule.h>
#include <stdlib.h>
#include <string.h>
#include "display.h"
#include "shell-global-private.h"
#include "shell-wm.h"
static void gnome_shell_plugin_dispose (GObject *object);
static void gnome_shell_plugin_finalize (GObject *object);
static void gnome_shell_plugin_start (MutterPlugin *plugin);
static void gnome_shell_plugin_minimize (MutterPlugin *plugin,
MutterWindow *actor);
static void gnome_shell_plugin_maximize (MutterPlugin *plugin,
MutterWindow *actor,
gint x,
gint y,
gint width,
gint height);
static void gnome_shell_plugin_unmaximize (MutterPlugin *plugin,
MutterWindow *actor,
gint x,
gint y,
gint width,
gint height);
static void gnome_shell_plugin_map (MutterPlugin *plugin,
MutterWindow *actor);
static void gnome_shell_plugin_destroy (MutterPlugin *plugin,
MutterWindow *actor);
static void gnome_shell_plugin_switch_workspace (MutterPlugin *plugin,
const GList **actors,
gint from,
gint to,
MetaMotionDirection direction);
static void gnome_shell_plugin_kill_effect (MutterPlugin *plugin,
MutterWindow *actor,
gulong events);
static gboolean gnome_shell_plugin_xevent_filter (MutterPlugin *plugin,
XEvent *event);
static const MutterPluginInfo *gnome_shell_plugin_plugin_info (MutterPlugin *plugin);
#define GNOME_TYPE_SHELL_PLUGIN (gnome_shell_plugin_get_type ())
#define GNOME_SHELL_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_SHELL_PLUGIN, GnomeShellPlugin))
#define GNOME_SHELL_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_SHELL_PLUGIN, GnomeShellPluginClass))
#define GNOME_IS_SHELL_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_SHELL_PLUGIN_TYPE))
#define GNOME_IS_SHELL_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_SHELL_PLUGIN))
#define GNOME_SHELL_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_SHELL_PLUGIN, GnomeShellPluginClass))
typedef struct _GnomeShellPlugin GnomeShellPlugin;
typedef struct _GnomeShellPluginClass GnomeShellPluginClass;
struct _GnomeShellPlugin
{
MutterPlugin parent;
GjsContext *gjs_context;
Atom panel_action;
Atom panel_action_run_dialog;
Atom panel_action_main_menu;
};
struct _GnomeShellPluginClass
{
MutterPluginClass parent_class;
};
/*
* Create the plugin struct; function pointers initialized in
* g_module_check_init().
*/
MUTTER_PLUGIN_DECLARE(GnomeShellPlugin, gnome_shell_plugin);
static void
gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
MutterPluginClass *plugin_class = MUTTER_PLUGIN_CLASS (klass);
gobject_class->dispose = gnome_shell_plugin_dispose;
gobject_class->finalize = gnome_shell_plugin_finalize;
plugin_class->start = gnome_shell_plugin_start;
plugin_class->map = gnome_shell_plugin_map;
plugin_class->minimize = gnome_shell_plugin_minimize;
plugin_class->maximize = gnome_shell_plugin_maximize;
plugin_class->unmaximize = gnome_shell_plugin_unmaximize;
plugin_class->destroy = gnome_shell_plugin_destroy;
plugin_class->switch_workspace = gnome_shell_plugin_switch_workspace;
plugin_class->kill_effect = gnome_shell_plugin_kill_effect;
plugin_class->xevent_filter = gnome_shell_plugin_xevent_filter;
plugin_class->plugin_info = gnome_shell_plugin_plugin_info;
}
static void
gnome_shell_plugin_init (GnomeShellPlugin *shell_plugin)
{
_shell_global_set_plugin (shell_global_get(), MUTTER_PLUGIN(shell_plugin));
meta_prefs_override_preference_location ("/apps/metacity/general/button_layout",
"/desktop/gnome/shell/windows/button_layout");
}
static void
gnome_shell_plugin_start (MutterPlugin *plugin)
{
GnomeShellPlugin *shell_plugin = GNOME_SHELL_PLUGIN (plugin);
MetaScreen *screen;
MetaDisplay *display;
GError *error = NULL;
int status;
const char *shell_js;
char **search_path;
ClutterBackend *backend;
cairo_font_options_t *font_options;
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
/* 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);
/* 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 ();
font_options = cairo_font_options_create ();
/* Default options for everything is reasonable; except that
* we want to turn off 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.
*/
cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_GRAY);
clutter_backend_set_font_options (backend, font_options);
cairo_font_options_destroy (font_options);
screen = mutter_plugin_get_screen (plugin);
display = meta_screen_get_display (screen);
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 = gjs_context_new_with_search_path(search_path);
g_strfreev(search_path);
_shell_global_set_gjs_context (shell_global_get (), shell_plugin->gjs_context);
if (!gjs_context_eval (shell_plugin->gjs_context,
"const Main = imports.ui.main; Main.start();",
-1,
"<main>",
&status,
&error))
{
g_message ("Execution of main.js threw exception: %s", error->message);
g_error_free (error);
/* We just exit() here, since in a development environment you'll get the
* error in your shell output, and it's way better than a busted WM,
* which typically manifests as a white screen.
*
* In production, we shouldn't crash =) But if we do, we should get
* restarted by the session infrastructure, which is likely going
* to be better than some undefined state.
*
* If there was a generic "hook into bug-buddy for non-C crashes"
* infrastructure, here would be the place to put it.
*/
exit (1);
}
}
static void
gnome_shell_plugin_dispose (GObject *object)
{
G_OBJECT_CLASS(gnome_shell_plugin_parent_class)->dispose (object);
}
static void
gnome_shell_plugin_finalize (GObject *object)
{
G_OBJECT_CLASS(gnome_shell_plugin_parent_class)->finalize (object);
}
static ShellWM *
get_shell_wm (void)
{
ShellWM *wm;
g_object_get (shell_global_get (),
"window-manager", &wm,
NULL);
/* drop extra ref added by g_object_get */
g_object_unref (wm);
return wm;
}
static void
gnome_shell_plugin_minimize (MutterPlugin *plugin,
MutterWindow *actor)
{
_shell_wm_minimize (get_shell_wm (),
actor);
}
static void
gnome_shell_plugin_maximize (MutterPlugin *plugin,
MutterWindow *actor,
gint x,
gint y,
gint width,
gint height)
{
_shell_wm_maximize (get_shell_wm (),
actor, x, y, width, height);
}
static void
gnome_shell_plugin_unmaximize (MutterPlugin *plugin,
MutterWindow *actor,
gint x,
gint y,
gint width,
gint height)
{
_shell_wm_unmaximize (get_shell_wm (),
actor, x, y, width, height);
}
static void
gnome_shell_plugin_map (MutterPlugin *plugin,
MutterWindow *actor)
{
_shell_wm_map (get_shell_wm (),
actor);
}
static void
gnome_shell_plugin_destroy (MutterPlugin *plugin,
MutterWindow *actor)
{
_shell_wm_destroy (get_shell_wm (),
actor);
}
static void
gnome_shell_plugin_switch_workspace (MutterPlugin *plugin,
const GList **actors,
gint from,
gint to,
MetaMotionDirection direction)
{
_shell_wm_switch_workspace (get_shell_wm(),
actors, from, to, direction);
}
static void
gnome_shell_plugin_kill_effect (MutterPlugin *plugin,
MutterWindow *actor,
gulong events)
{
_shell_wm_kill_effect (get_shell_wm(),
actor, events);
}
static gboolean
gnome_shell_plugin_xevent_filter (MutterPlugin *plugin,
XEvent *xev)
{
return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
}
static const
MutterPluginInfo *gnome_shell_plugin_plugin_info (MutterPlugin *plugin)
{
static const MutterPluginInfo info = {
.name = "GNOME Shell",
.version = "0.1",
.author = "Various",
.license = "GPLv2+",
.description = "Provides GNOME Shell core functionality"
};
return &info;
}