/** * shell_global_grab_keyboard: * @global: a #ShellGlobal * * Grab the keyboard to the stage window. The stage will receive * all keyboard events until shell_global_ungrab_keyboard() is called. * This is appropriate to do when the desktop goes into a special * mode where no normal global key shortcuts or application keyboard * processing should happen. */ gboolean shell_global_grab_keyboard (ShellGlobal *global) { MetaScreen *screen = mutter_plugin_get_screen (global->plugin); MetaDisplay *display = meta_screen_get_display (screen); Display *xdisplay = meta_display_get_xdisplay (display); ClutterStage *stage = CLUTTER_STAGE (mutter_plugin_get_stage (global->plugin)); Window stagewin = clutter_x11_get_stage_window (stage); /* FIXME: we need to coordinate with the rest of Metacity or we * may grab the keyboard away from other portions of Metacity * and leave Metacity in a confused state. An X client is allowed * to overgrab itself, though not allowed to grab they keyboard * away from another applications. */ if (global->keyboard_grabbed) return FALSE; if (XGrabKeyboard (xdisplay, stagewin, False, /* owner_events - steal events from the rest of metacity */ GrabModeAsync, GrabModeAsync, CurrentTime) != Success) return FALSE; /* probably AlreadyGrabbed, some other app has a keyboard grab */ global->keyboard_grabbed = TRUE; return TRUE; }
/** * shell_global_create_root_pixmap_actor: * @global: a #ShellGlobal * * Creates an actor showing the root window pixmap. * * Return value: (transfer none): a #ClutterActor with the root window pixmap. * The actor is floating, hence (transfer none). */ ClutterActor * shell_global_create_root_pixmap_actor (ShellGlobal *global) { GdkWindow *window; ClutterActor *stage; ClutterColor stage_color; /* The actor created is actually a ClutterClone of global->root_pixmap. */ if (global->root_pixmap == NULL) { global->root_pixmap = clutter_glx_texture_pixmap_new (); clutter_texture_set_repeat (CLUTTER_TEXTURE (global->root_pixmap), TRUE, TRUE); /* The low and medium quality filters give nearest-neighbor resizing. */ clutter_texture_set_filter_quality (CLUTTER_TEXTURE (global->root_pixmap), CLUTTER_TEXTURE_QUALITY_HIGH); /* Initialize to the stage color, since that's what will be seen * in the main view if there's no actual background window. */ stage = mutter_plugin_get_stage (global->plugin); clutter_stage_get_color (CLUTTER_STAGE (stage), &stage_color); clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (global->root_pixmap), /* ClutterColor has the same layout * as one pixel of RGB(A) data. */ (const guchar *)&stage_color, FALSE, /* w, h, rowstride, bpp, flags */ 1, 1, 3, 3, 0, NULL); /* We can only clone an actor within a stage, so we hide the source * texture then add it to the stage */ clutter_actor_hide (global->root_pixmap); clutter_container_add_actor (CLUTTER_CONTAINER (stage), global->root_pixmap); /* This really should never happen; but just in case... */ g_signal_connect (global->root_pixmap, "destroy", G_CALLBACK (root_pixmap_destroy), global); /* Metacity handles changes to some root window properties in its global * event filter, though not _XROOTPMAP_ID. For all root window property * changes, the global filter returns GDK_FILTER_CONTINUE, so our * window specific filter will be called after the global one. * * Because Metacity is already handling root window property updates, * we don't have to worry about adding the PropertyChange mask to the * root window to get PropertyNotify events. */ window = gdk_get_default_root_window (); gdk_window_add_filter (window, root_window_filter, global); update_root_window_pixmap (global); } return clutter_clone_new (global->root_pixmap); }
/** * shell_global_begin_modal: * @global: a #ShellGlobal * * Grabs the keyboard and mouse to the stage window. The stage will * receive all keyboard and mouse events until shell_global_end_modal() * is called. This is used to implement "modes" for the shell, such as the * overview mode or the "looking glass" debug overlay, that block * application and normal key shortcuts. * * Returns value: %TRUE if we succesfully entered the mode. %FALSE if we couldn't * enter the mode. Failure may occur because an application has the pointer * or keyboard grabbed, because Mutter is in a mode itself like moving a * window or alt-Tab window selection, or because shell_global_begin_modal() * was previouly called. */ gboolean shell_global_begin_modal (ShellGlobal *global, guint32 timestamp) { ClutterStage *stage = CLUTTER_STAGE (mutter_plugin_get_stage (global->plugin)); Window stagewin = clutter_x11_get_stage_window (stage); return mutter_plugin_begin_modal (global->plugin, stagewin, None, 0, timestamp); }
static void shell_global_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { ShellGlobal *global = SHELL_GLOBAL (object); switch (prop_id) { case PROP_OVERLAY_GROUP: g_value_set_object (value, mutter_plugin_get_overlay_group (global->plugin)); break; case PROP_SCREEN: g_value_set_object (value, shell_global_get_screen (global)); break; case PROP_SCREEN_WIDTH: { int width, height; mutter_plugin_query_screen_size (global->plugin, &width, &height); g_value_set_int (value, width); } break; case PROP_SCREEN_HEIGHT: { int width, height; mutter_plugin_query_screen_size (global->plugin, &width, &height); g_value_set_int (value, height); } break; case PROP_STAGE: g_value_set_object (value, mutter_plugin_get_stage (global->plugin)); break; case PROP_WINDOW_GROUP: g_value_set_object (value, mutter_plugin_get_window_group (global->plugin)); break; case PROP_WINDOW_MANAGER: g_value_set_object (value, global->wm); break; case PROP_DATADIR: g_value_set_string (value, global->datadir); break; case PROP_IMAGEDIR: g_value_set_string (value, global->imagedir); break; case PROP_CONFIGDIR: g_value_set_string (value, global->configdir); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void global_plugin_notify_screen (GObject *gobject, GParamSpec *pspec, gpointer data) { ShellGlobal *global = SHELL_GLOBAL (data); ClutterActor *stage = mutter_plugin_get_stage (MUTTER_PLUGIN (gobject)); g_signal_connect (stage, "notify::width", G_CALLBACK (global_stage_notify_width), global); g_signal_connect (stage, "notify::height", G_CALLBACK (global_stage_notify_height), global); }
/** * shell_global_create_root_pixmap_actor: * @global: a #ShellGlobal * * Creates an actor showing the root window pixmap. * * Return value: (transfer none): a #ClutterActor with the root window pixmap. * The actor is floating, hence (transfer none). */ ClutterActor * shell_global_create_root_pixmap_actor (ShellGlobal *global) { GdkWindow *window; ClutterActor *stage; /* The actor created is actually a ClutterClone of global->root_pixmap. */ if (global->root_pixmap == NULL) { global->root_pixmap = clutter_glx_texture_pixmap_new (); /* The low and medium quality filters give nearest-neighbor resizing. */ clutter_texture_set_filter_quality (CLUTTER_TEXTURE (global->root_pixmap), CLUTTER_TEXTURE_QUALITY_HIGH); /* We can only clone an actor within a stage, so we hide the source * texture then add it to the stage */ clutter_actor_hide (global->root_pixmap); stage = mutter_plugin_get_stage (global->plugin); clutter_container_add_actor (CLUTTER_CONTAINER (stage), global->root_pixmap); g_signal_connect (global->root_pixmap, "paint", G_CALLBACK (root_pixmap_paint), NULL); /* This really should never happen; but just in case... */ g_signal_connect (global->root_pixmap, "destroy", G_CALLBACK (root_pixmap_destroy), global); /* Metacity handles changes to some root window properties in its global * event filter, though not _XROOTPMAP_ID. For all root window property * changes, the global filter returns GDK_FILTER_CONTINUE, so our * window specific filter will be called after the global one. * * Because Metacity is already handling root window property updates, * we don't have to worry about adding the PropertyChange mask to the * root window to get PropertyNotify events. */ window = gdk_get_default_root_window (); gdk_window_add_filter (window, root_window_filter, global); update_root_window_pixmap (global); } return clutter_clone_new (global->root_pixmap); }