mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 18:11:05 -05:00
Citadel changes to Mutter
This commit is contained in:
parent
4f6c918470
commit
b8e4ce7c80
@ -641,8 +641,13 @@ meta_compositor_switch_workspace (MetaCompositor *compositor,
|
|||||||
meta_compositor_get_instance_private (compositor);
|
meta_compositor_get_instance_private (compositor);
|
||||||
gint to_indx, from_indx;
|
gint to_indx, from_indx;
|
||||||
|
|
||||||
to_indx = meta_workspace_index (to);
|
if (direction == META_MOTION_CONTEXT_SWITCH) {
|
||||||
from_indx = meta_workspace_index (from);
|
to_indx = meta_workspace_get_id (to);
|
||||||
|
from_indx = meta_workspace_get_id (from);
|
||||||
|
} else {
|
||||||
|
to_indx = meta_workspace_index (to);
|
||||||
|
from_indx = meta_workspace_index (from);
|
||||||
|
}
|
||||||
|
|
||||||
priv->switch_workspace_in_progress++;
|
priv->switch_workspace_in_progress++;
|
||||||
|
|
||||||
|
@ -29,6 +29,36 @@
|
|||||||
#include "meta/types.h"
|
#include "meta/types.h"
|
||||||
#include "meta/meta-workspace-manager.h"
|
#include "meta/meta-workspace-manager.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Stores list of MetaWorkspaces and pointer to an active MetaWorkspace. When this context becomes
|
||||||
|
// the current context, the workspace fields are swapped into the corresponding fields in
|
||||||
|
// MetaWorkspaceManager.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
struct _MetaWorkspaceContext
|
||||||
|
{
|
||||||
|
|
||||||
|
GObject parent;
|
||||||
|
// Link back to MetaWorkspaceManager
|
||||||
|
MetaWorkspaceManager *manager;
|
||||||
|
|
||||||
|
// MetaWorkspace list belonging to this context. Copied to field with same name in
|
||||||
|
// MetaWorkspaceManager when this context is active. Any code which changes this list
|
||||||
|
// must make sure this context is not currently active in which case the list in
|
||||||
|
// MetaWorkspaceManager must be changed instead.
|
||||||
|
GList *workspaces;
|
||||||
|
|
||||||
|
// Active MetaWorkspace for this context. Also copied to workspace manager upon activation.
|
||||||
|
// The rule above about not writing if context is currently active also applies to this field.
|
||||||
|
MetaWorkspace *active_workspace;
|
||||||
|
|
||||||
|
// PID namespace
|
||||||
|
gchar *namespace;
|
||||||
|
|
||||||
|
// A unique ID value for this context.
|
||||||
|
guint id;
|
||||||
|
};
|
||||||
|
|
||||||
struct _MetaWorkspaceManager
|
struct _MetaWorkspaceManager
|
||||||
{
|
{
|
||||||
GObject parent;
|
GObject parent;
|
||||||
@ -36,8 +66,21 @@ struct _MetaWorkspaceManager
|
|||||||
MetaDisplay *display;
|
MetaDisplay *display;
|
||||||
MetaWorkspace *active_workspace;
|
MetaWorkspace *active_workspace;
|
||||||
|
|
||||||
|
GList *all_workspaces;
|
||||||
GList *workspaces;
|
GList *workspaces;
|
||||||
|
|
||||||
|
// List of WorkspaceContext
|
||||||
|
GList *context_list;
|
||||||
|
|
||||||
|
gchar *mutter_namespace;
|
||||||
|
|
||||||
|
// Current active WorkspaceContext. MetaWorkspaceManager state (workspaces, active_workspace)
|
||||||
|
// will be saved here when a new WorkspaceContext is made active.
|
||||||
|
MetaWorkspaceContext *active_context;
|
||||||
|
|
||||||
|
// The next id value to allocate when creating a new WorkspaceContext
|
||||||
|
guint next_context_id;
|
||||||
|
|
||||||
int rows_of_workspaces;
|
int rows_of_workspaces;
|
||||||
int columns_of_workspaces;
|
int columns_of_workspaces;
|
||||||
MetaDisplayCorner starting_corner;
|
MetaDisplayCorner starting_corner;
|
||||||
@ -92,3 +135,29 @@ META_EXPORT_TEST
|
|||||||
void meta_workspace_manager_update_num_workspaces (MetaWorkspaceManager *workspace_manager,
|
void meta_workspace_manager_update_num_workspaces (MetaWorkspaceManager *workspace_manager,
|
||||||
guint32 timestamp,
|
guint32 timestamp,
|
||||||
int new_num);
|
int new_num);
|
||||||
|
|
||||||
|
MetaWorkspaceContext *meta_workspace_context_new (MetaWorkspaceManager *manager, const char *namespace);
|
||||||
|
|
||||||
|
void meta_workspace_context_make_active (MetaWorkspaceContext *context);
|
||||||
|
|
||||||
|
MetaWorkspaceContext *meta_workspace_manager_lookup_context (MetaWorkspaceManager *workspace_manager,
|
||||||
|
guint context_id);
|
||||||
|
|
||||||
|
|
||||||
|
void meta_workspace_manager_append_context_workspace (MetaWorkspaceManager *manager,
|
||||||
|
MetaWorkspace *workspace);
|
||||||
|
|
||||||
|
void meta_workspace_manager_remove_context_workspace (MetaWorkspaceManager *manager,
|
||||||
|
MetaWorkspace *workspace);
|
||||||
|
|
||||||
|
int meta_workspace_manager_context_workspace_index (MetaWorkspaceManager *workspace_manager,
|
||||||
|
MetaWorkspace *workspace);
|
||||||
|
|
||||||
|
int meta_workspace_manager_get_workspace_id (MetaWorkspaceManager *workspace_manager,
|
||||||
|
MetaWorkspace *workspace);
|
||||||
|
MetaWorkspace *
|
||||||
|
meta_workspace_manager_lookup_workspace_by_id (MetaWorkspaceManager *workspace_manager, int workspace_id);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_workspace_manager_is_window_on_foreign_context (MetaWorkspaceManager *workspace_manager, MetaWindow *window);
|
||||||
|
|
||||||
|
@ -44,6 +44,9 @@ enum
|
|||||||
WORKSPACES_REORDERED,
|
WORKSPACES_REORDERED,
|
||||||
ACTIVE_WORKSPACE_CHANGED,
|
ACTIVE_WORKSPACE_CHANGED,
|
||||||
SHOWING_DESKTOP_CHANGED,
|
SHOWING_DESKTOP_CHANGED,
|
||||||
|
CONTEXT_SWITCHED,
|
||||||
|
CONTEXT_WINDOW_MOVED,
|
||||||
|
CONTEXT_REMOVED,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -163,6 +166,29 @@ meta_workspace_manager_class_init (MetaWorkspaceManagerClass *klass)
|
|||||||
0, NULL, NULL, NULL,
|
0, NULL, NULL, NULL,
|
||||||
G_TYPE_NONE, 0);
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
|
workspace_manager_signals[CONTEXT_SWITCHED] =
|
||||||
|
g_signal_new ("context-switched",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0, NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
|
workspace_manager_signals[CONTEXT_WINDOW_MOVED] =
|
||||||
|
g_signal_new("context-window-moved",
|
||||||
|
G_TYPE_FROM_CLASS(klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0, NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 1,
|
||||||
|
META_TYPE_WINDOW);
|
||||||
|
|
||||||
|
workspace_manager_signals[CONTEXT_REMOVED] =
|
||||||
|
g_signal_new("context-removed",
|
||||||
|
G_TYPE_FROM_CLASS(klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0, NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 1,
|
||||||
|
G_TYPE_INT);
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
g_object_class_install_property (object_class,
|
||||||
PROP_LAYOUT_COLUMNS,
|
PROP_LAYOUT_COLUMNS,
|
||||||
g_param_spec_int ("layout-columns", NULL, NULL,
|
g_param_spec_int ("layout-columns", NULL, NULL,
|
||||||
@ -180,6 +206,7 @@ meta_workspace_manager_class_init (MetaWorkspaceManagerClass *klass)
|
|||||||
g_param_spec_int ("n-workspaces", NULL, NULL,
|
g_param_spec_int ("n-workspaces", NULL, NULL,
|
||||||
1, G_MAXINT, 1,
|
1, G_MAXINT, 1,
|
||||||
G_PARAM_READABLE));
|
G_PARAM_READABLE));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -192,7 +219,7 @@ meta_workspace_manager_reload_work_areas (MetaWorkspaceManager *workspace_manage
|
|||||||
{
|
{
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
for (l = workspace_manager->workspaces; l; l = l->next)
|
for (l = workspace_manager->all_workspaces; l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaWorkspace *workspace = l->data;
|
MetaWorkspace *workspace = l->data;
|
||||||
|
|
||||||
@ -209,12 +236,24 @@ meta_workspace_manager_new (MetaDisplay *display)
|
|||||||
|
|
||||||
workspace_manager->display = display;
|
workspace_manager->display = display;
|
||||||
workspace_manager->active_workspace = NULL;
|
workspace_manager->active_workspace = NULL;
|
||||||
|
workspace_manager->all_workspaces = NULL;
|
||||||
workspace_manager->workspaces = NULL;
|
workspace_manager->workspaces = NULL;
|
||||||
workspace_manager->rows_of_workspaces = 1;
|
workspace_manager->rows_of_workspaces = 1;
|
||||||
workspace_manager->columns_of_workspaces = -1;
|
workspace_manager->columns_of_workspaces = -1;
|
||||||
workspace_manager->vertical_workspaces = FALSE;
|
workspace_manager->vertical_workspaces = FALSE;
|
||||||
workspace_manager->starting_corner = META_DISPLAY_TOPLEFT;
|
workspace_manager->starting_corner = META_DISPLAY_TOPLEFT;
|
||||||
|
|
||||||
|
workspace_manager->context_list = NULL;
|
||||||
|
workspace_manager->active_context = NULL;
|
||||||
|
workspace_manager->next_context_id = 1;
|
||||||
|
workspace_manager->mutter_namespace = meta_read_pid_namespace (getpid());
|
||||||
|
|
||||||
|
MetaWorkspaceContext *context = meta_workspace_context_new (workspace_manager, NULL);
|
||||||
|
|
||||||
|
workspace_manager->workspaces = g_steal_pointer (&context->workspaces);
|
||||||
|
workspace_manager->active_workspace = g_steal_pointer (&context->active_workspace);
|
||||||
|
workspace_manager->active_context = context;
|
||||||
|
|
||||||
/* This is the default layout extracted from default
|
/* This is the default layout extracted from default
|
||||||
* variable values in update_num_workspaces ()
|
* variable values in update_num_workspaces ()
|
||||||
* This can be overridden using _NET_DESKTOP_LAYOUT in
|
* This can be overridden using _NET_DESKTOP_LAYOUT in
|
||||||
@ -225,11 +264,6 @@ meta_workspace_manager_new (MetaDisplay *display)
|
|||||||
1,
|
1,
|
||||||
-1);
|
-1);
|
||||||
|
|
||||||
/* There must be at least one workspace at all times,
|
|
||||||
* so create that required workspace.
|
|
||||||
*/
|
|
||||||
meta_workspace_new (workspace_manager);
|
|
||||||
|
|
||||||
meta_workspace_manager_init_workspaces (workspace_manager);
|
meta_workspace_manager_init_workspaces (workspace_manager);
|
||||||
|
|
||||||
meta_prefs_add_listener (prefs_changed_callback, workspace_manager);
|
meta_prefs_add_listener (prefs_changed_callback, workspace_manager);
|
||||||
@ -280,6 +314,9 @@ MetaWorkspace *
|
|||||||
meta_workspace_manager_get_workspace_by_index (MetaWorkspaceManager *workspace_manager,
|
meta_workspace_manager_get_workspace_by_index (MetaWorkspaceManager *workspace_manager,
|
||||||
int idx)
|
int idx)
|
||||||
{
|
{
|
||||||
|
if ((idx >> 16) & 0xFFFF) {
|
||||||
|
return meta_workspace_manager_lookup_workspace_by_id (workspace_manager, idx);
|
||||||
|
}
|
||||||
return g_list_nth_data (workspace_manager->workspaces, idx);
|
return g_list_nth_data (workspace_manager->workspaces, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -988,7 +1025,7 @@ meta_workspace_manager_unshow_desktop (MetaWorkspaceManager *workspace_manager)
|
|||||||
GList *
|
GList *
|
||||||
meta_workspace_manager_get_workspaces (MetaWorkspaceManager *workspace_manager)
|
meta_workspace_manager_get_workspaces (MetaWorkspaceManager *workspace_manager)
|
||||||
{
|
{
|
||||||
return workspace_manager->workspaces;
|
return workspace_manager->all_workspaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -1002,6 +1039,17 @@ meta_workspace_manager_get_active_workspace_index (MetaWorkspaceManager *workspa
|
|||||||
return meta_workspace_index (active);
|
return meta_workspace_index (active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
meta_workspace_manager_get_active_workspace_id (MetaWorkspaceManager *workspace_manager)
|
||||||
|
{
|
||||||
|
MetaWorkspace *active = workspace_manager->active_workspace;
|
||||||
|
|
||||||
|
if (!active)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return meta_workspace_get_id (active);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_workspace_manager_get_active_workspace:
|
* meta_workspace_manager_get_active_workspace:
|
||||||
* @workspace_manager: A #MetaWorkspaceManager
|
* @workspace_manager: A #MetaWorkspaceManager
|
||||||
@ -1020,9 +1068,15 @@ meta_workspace_manager_workspace_switched (MetaWorkspaceManager *workspace_manag
|
|||||||
int to,
|
int to,
|
||||||
MetaMotionDirection direction)
|
MetaMotionDirection direction)
|
||||||
{
|
{
|
||||||
g_signal_emit (workspace_manager,
|
if (direction == META_MOTION_CONTEXT_SWITCH) {
|
||||||
workspace_manager_signals[WORKSPACE_SWITCHED], 0,
|
g_signal_emit (workspace_manager,
|
||||||
from, to, direction);
|
workspace_manager_signals[CONTEXT_SWITCHED],
|
||||||
|
0, NULL);
|
||||||
|
} else {
|
||||||
|
g_signal_emit (workspace_manager,
|
||||||
|
workspace_manager_signals[WORKSPACE_SWITCHED], 0,
|
||||||
|
from, to, direction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1045,3 +1099,379 @@ prefs_changed_callback (MetaPreference pref,
|
|||||||
timestamp, new_num);
|
timestamp, new_num);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_workspace_manager_set_builtin_struts_all:
|
||||||
|
* @workspace_manager: a #MetaWorkspaceManager
|
||||||
|
* @struts: (element-type Meta.Strut) (transfer none): list of #MetaStrut
|
||||||
|
*
|
||||||
|
* Sets a list of struts on every workspace that will be used in addition to the struts
|
||||||
|
* of the windows in the workspace when computing the work area of
|
||||||
|
* the workspace.
|
||||||
|
*/
|
||||||
|
void meta_workspace_manager_set_builtin_struts_all(MetaWorkspaceManager *workspace_manager,
|
||||||
|
GSList *struts)
|
||||||
|
{
|
||||||
|
GList *context_iter = workspace_manager->context_list;
|
||||||
|
while (context_iter) {
|
||||||
|
MetaWorkspaceContext *context = context_iter->data;
|
||||||
|
for (GList *ws_iter = context->workspaces; ws_iter; ws_iter = ws_iter->next) {
|
||||||
|
MetaWorkspace *workspace = ws_iter->data;
|
||||||
|
meta_workspace_set_builtin_struts(workspace, struts);
|
||||||
|
}
|
||||||
|
context_iter = context_iter->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_workspace_manager_lookup_context:
|
||||||
|
* @workspace_manager: a #MetaWorkspaceManager
|
||||||
|
* @context_id: id value of context to look up
|
||||||
|
*
|
||||||
|
* Look up WorkspaceContext by id and return it. If no context is found with
|
||||||
|
* the specified id the return value is %NULL.
|
||||||
|
*
|
||||||
|
* Return value: (transfer none) (nullable): the workspace context with the specified id
|
||||||
|
* or %NULL if no context with matching id exists.
|
||||||
|
*/
|
||||||
|
MetaWorkspaceContext *
|
||||||
|
meta_workspace_manager_lookup_context (MetaWorkspaceManager *workspace_manager, guint context_id)
|
||||||
|
{
|
||||||
|
for (GList *iter = workspace_manager->context_list; iter; iter = iter->next) {
|
||||||
|
MetaWorkspaceContext *context = iter->data;
|
||||||
|
if (context_id == context->id) {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
meta_workspace_manager_mutter_namespace (MetaWorkspaceManager *workspace_manager)
|
||||||
|
{
|
||||||
|
if (!workspace_manager->mutter_namespace) {
|
||||||
|
workspace_manager->mutter_namespace = meta_read_pid_namespace (getpid());
|
||||||
|
}
|
||||||
|
return workspace_manager->mutter_namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return pointer to the live workspace list depending on whether or not the context is currently active.
|
||||||
|
* While a workspace context is active, the list must be accessed through the pointer workspace_manager->workspaces
|
||||||
|
*/
|
||||||
|
GList **
|
||||||
|
meta_workspace_manager_workspace_list_for_context (MetaWorkspaceManager *workspace_manager, guint context_id)
|
||||||
|
{
|
||||||
|
if (workspace_manager->active_context && workspace_manager->active_context->id == context_id) {
|
||||||
|
return &workspace_manager->workspaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWorkspaceContext *context = meta_workspace_manager_lookup_context (workspace_manager, context_id);
|
||||||
|
|
||||||
|
if (context) {
|
||||||
|
return &context->workspaces;
|
||||||
|
} else {
|
||||||
|
g_warning ("MetaWorkspaceManager: Failed to find context workspace list (context_id = %d)", context_id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_workspace_manager_append_context_workspace (MetaWorkspaceManager *workspace_manager, MetaWorkspace *workspace)
|
||||||
|
{
|
||||||
|
GList **p_workspaces = meta_workspace_manager_workspace_list_for_context (workspace_manager, workspace->context_id);
|
||||||
|
if (p_workspaces) {
|
||||||
|
*p_workspaces = g_list_append (*p_workspaces, workspace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_workspace_manager_remove_context_workspace (MetaWorkspaceManager *workspace_manager, MetaWorkspace *workspace)
|
||||||
|
{
|
||||||
|
GList **p_workspaces = meta_workspace_manager_workspace_list_for_context (workspace_manager, workspace->context_id);
|
||||||
|
if (p_workspaces) {
|
||||||
|
*p_workspaces = g_list_remove (*p_workspaces, workspace);
|
||||||
|
}
|
||||||
|
workspace_manager->all_workspaces = g_list_remove (workspace_manager->all_workspaces, workspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
workspace_index_in_context (MetaWorkspaceManager *workspace_manager, MetaWorkspace *workspace)
|
||||||
|
{
|
||||||
|
GList **p_workspaces = meta_workspace_manager_workspace_list_for_context (workspace_manager, workspace->context_id);
|
||||||
|
if (p_workspaces) {
|
||||||
|
return g_list_index (*p_workspaces, workspace);
|
||||||
|
} else {
|
||||||
|
g_warning ("MetaWorkspaceManager: Could not find context for id=%d in workspace_index_in_context()", workspace->context_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
meta_workspace_manager_get_workspace_id (MetaWorkspaceManager *workspace_manager, MetaWorkspace *workspace)
|
||||||
|
{
|
||||||
|
int idx = workspace_index_in_context (workspace_manager, workspace);
|
||||||
|
|
||||||
|
if (idx >= 0) {
|
||||||
|
idx |= (int)(workspace->context_id << 16);
|
||||||
|
} else {
|
||||||
|
g_warning ("MetaWorkspaceManager: Workspace with context_id = %d not found in meta_workspace_manager_get_workspace_id()", workspace->context_id);
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
meta_workspace_manager_context_workspace_index (MetaWorkspaceManager *workspace_manager, MetaWorkspace *workspace)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!(workspace_manager->active_context && workspace_manager->active_context->id == workspace->context_id)) {
|
||||||
|
guint active = (workspace_manager->active_context) ? (workspace_manager->active_context->id) : 0;
|
||||||
|
g_warning ("MetaWorkspaceManager: context_workspace_index() called on workspace not in active context. (ws->context_id = %d, active->context_id=%d)",
|
||||||
|
workspace->context_id, active);
|
||||||
|
}
|
||||||
|
|
||||||
|
int idx = workspace_index_in_context (workspace_manager, workspace);
|
||||||
|
if (idx < 0) {
|
||||||
|
g_warning ("MetaWorkspaceManager: Failed to find workspace with context_id=%d in context_workspace_index()",
|
||||||
|
workspace->context_id);
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWorkspace *
|
||||||
|
meta_workspace_manager_lookup_workspace_by_id (MetaWorkspaceManager *workspace_manager, int workspace_id)
|
||||||
|
{
|
||||||
|
uint context_id = (workspace_id >> 16) & 0xFFFF;
|
||||||
|
if (context_id) {
|
||||||
|
GList **p_workspaces = meta_workspace_manager_workspace_list_for_context (workspace_manager, context_id);
|
||||||
|
int idx = workspace_id & 0xFFFF;
|
||||||
|
if (p_workspaces) {
|
||||||
|
return g_list_nth_data (*p_workspaces, idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_workspace_manager_context_for_namespace:
|
||||||
|
* @workspace_manager: a #MetaWorkspaceManager
|
||||||
|
* @namespace: namespace of context
|
||||||
|
*
|
||||||
|
* Find an existing WorkspaceContext for the specified namespace. If no WorkspaceContext
|
||||||
|
* currently exists for namespace create a new one.
|
||||||
|
*
|
||||||
|
* Return value: (transfer none): the workspace context for the specified namespace
|
||||||
|
*/
|
||||||
|
MetaWorkspaceContext *
|
||||||
|
meta_workspace_manager_context_for_namespace (MetaWorkspaceManager *workspace_manager, const gchar *namespace)
|
||||||
|
{
|
||||||
|
MetaWorkspaceContext *anonymous_context = NULL;
|
||||||
|
|
||||||
|
for (GList *iter = workspace_manager->context_list; iter; iter = iter->next) {
|
||||||
|
MetaWorkspaceContext *context = iter->data;
|
||||||
|
if (context->namespace == NULL && anonymous_context == NULL) {
|
||||||
|
anonymous_context = context;
|
||||||
|
} else if (!g_strcmp0 (context->namespace, namespace )) {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anonymous_context) {
|
||||||
|
anonymous_context->namespace = g_strdup (namespace);
|
||||||
|
return anonymous_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
return meta_workspace_context_new (workspace_manager, namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
meta_workspace_manager_active_context_id (MetaWorkspaceManager *workspace_manager)
|
||||||
|
{
|
||||||
|
if (workspace_manager->active_context) {
|
||||||
|
return workspace_manager->active_context->id;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MetaWorkspaceContext, meta_workspace_context, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
guint
|
||||||
|
meta_workspace_context_id (MetaWorkspaceContext *context)
|
||||||
|
{
|
||||||
|
return context->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_workspace_context_remove (MetaWorkspaceContext *context)
|
||||||
|
{
|
||||||
|
if (meta_workspace_context_is_current (context)) {
|
||||||
|
g_warning ("MetaWorkspaceManager: attempt to remove active context ignored");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (GList *iter = context->workspaces; iter; iter = iter->next) {
|
||||||
|
MetaWorkspace *workspace = iter->data;
|
||||||
|
meta_workspace_relocate_windows (workspace, context->manager->active_workspace);
|
||||||
|
}
|
||||||
|
context->active_workspace = NULL;
|
||||||
|
g_list_free_full (g_steal_pointer(&context->workspaces), (GDestroyNotify) meta_workspace_remove);
|
||||||
|
|
||||||
|
g_signal_emit (context->manager, workspace_manager_signals[CONTEXT_REMOVED],
|
||||||
|
0, context->id);
|
||||||
|
|
||||||
|
g_clear_pointer (&context->namespace, g_free);
|
||||||
|
context->manager->context_list = g_list_remove (context->manager->context_list, context);
|
||||||
|
g_object_unref (context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_workspace_context_class_init (MetaWorkspaceContextClass *klass)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_workspace_context_init (MetaWorkspaceContext *context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWorkspaceContext *
|
||||||
|
meta_workspace_context_new (MetaWorkspaceManager *manager, const char *namespace)
|
||||||
|
{
|
||||||
|
guint context_id = manager->next_context_id++;
|
||||||
|
|
||||||
|
MetaWorkspaceContext *context = g_object_new (META_TYPE_WORKSPACE_CONTEXT, NULL);
|
||||||
|
|
||||||
|
context->manager = manager;
|
||||||
|
context->workspaces = NULL;
|
||||||
|
context->active_workspace = NULL;
|
||||||
|
context->namespace = NULL;
|
||||||
|
context->id = context_id;
|
||||||
|
|
||||||
|
if (namespace) {
|
||||||
|
context->namespace = g_strdup (namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
manager->context_list = g_list_append (manager->context_list, context);
|
||||||
|
|
||||||
|
context->active_workspace = meta_workspace_new_with_context_id (manager, context_id);
|
||||||
|
g_object_notify (G_OBJECT (manager), "n-workspaces");
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Synchronize the state stored in the MetaWorkspaceManager to 'context'
|
||||||
|
* by copying the relevant fields to the WorkspaceContext structure.
|
||||||
|
*
|
||||||
|
* The state which is saved is the list of workspaces and the active
|
||||||
|
* workspace pointer:
|
||||||
|
*
|
||||||
|
* workspace_manager->active_workspace
|
||||||
|
* workspace_manager->workspaces
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
workspace_context_sync_manager_state (MetaWorkspaceContext *context)
|
||||||
|
{
|
||||||
|
context->active_workspace = context->manager->active_workspace;
|
||||||
|
context->workspaces = context->manager->workspaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_workspace_context_is_current (MetaWorkspaceContext *context)
|
||||||
|
{
|
||||||
|
return context && context->manager->active_context == context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_workspace_context_get_active_workspace:
|
||||||
|
* @context: A #MetaWorkspaceContext
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): The current workspace for this context
|
||||||
|
*/
|
||||||
|
MetaWorkspace *
|
||||||
|
meta_workspace_context_get_active_workspace (MetaWorkspaceContext *context)
|
||||||
|
{
|
||||||
|
if (meta_workspace_context_is_current (context)) {
|
||||||
|
return context->manager->active_workspace;
|
||||||
|
} else {
|
||||||
|
return context->active_workspace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_workspace_context_move_window_to_context (MetaWorkspaceContext *context, MetaWindow *window)
|
||||||
|
{
|
||||||
|
if (!context->active_workspace) {
|
||||||
|
g_warning ("MetaWorkspaceContext: Cannot move window to context (%d) because no workspace is active", context->id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->workspace->context_id != context->id) {
|
||||||
|
meta_window_change_workspace (window, context->active_workspace);
|
||||||
|
g_signal_emit (context->manager, workspace_manager_signals[CONTEXT_WINDOW_MOVED], 0, window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_workspace_context_make_active (MetaWorkspaceContext *context) {
|
||||||
|
|
||||||
|
MetaWorkspaceManager *manager = context->manager;
|
||||||
|
|
||||||
|
workspace_context_sync_manager_state (manager->active_context);
|
||||||
|
|
||||||
|
manager->active_context = context;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not update manager->active_workspace because meta_workspace_activate() expects
|
||||||
|
* old value
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* steal pointer to avoid writing code elsewhere that changes this list while context is active */
|
||||||
|
manager->workspaces = g_steal_pointer (&context->workspaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Activate a WorkspaceContext instance by copying the context state fields
|
||||||
|
* into the MetaWorkspaceManager structure.
|
||||||
|
*
|
||||||
|
* If 'context' is already the current WorkspaceContext do nothing.
|
||||||
|
*
|
||||||
|
* If some other context is active, save the context fields by calling
|
||||||
|
*
|
||||||
|
* workspace_context_sync_manager_state()
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
meta_workspace_context_activate (MetaWorkspaceContext *context)
|
||||||
|
{
|
||||||
|
if (meta_workspace_context_is_current (context)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_workspace_context_make_active (context);
|
||||||
|
|
||||||
|
guint32 timestamp;
|
||||||
|
|
||||||
|
timestamp = meta_display_get_current_time_roundtrip (context->manager->display);
|
||||||
|
|
||||||
|
/* Will set manager->active_workspace from context->active_workspace */
|
||||||
|
meta_workspace_activate ( g_steal_pointer (&context->active_workspace), timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_workspace_manager_is_window_on_foreign_context (MetaWorkspaceManager *workspace_manager, MetaWindow *window)
|
||||||
|
{
|
||||||
|
const char *ns = meta_window_namespace (window);
|
||||||
|
|
||||||
|
if (!ns || !g_strcmp0 (ns, workspace_manager->mutter_namespace) || !window->workspace) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWorkspaceContext *context = meta_workspace_manager_context_for_namespace (workspace_manager, ns);
|
||||||
|
return context->id != window->workspace->context_id;
|
||||||
|
}
|
||||||
|
@ -56,3 +56,6 @@ meta_timeval_to_microseconds (const struct timeval *tv)
|
|||||||
|
|
||||||
#define META_CONTAINER_OF(ptr, type, member) \
|
#define META_CONTAINER_OF(ptr, type, member) \
|
||||||
(type *) ((uint8_t *) (ptr) - G_STRUCT_OFFSET (type, member))
|
(type *) ((uint8_t *) (ptr) - G_STRUCT_OFFSET (type, member))
|
||||||
|
|
||||||
|
char * meta_read_pid_namespace (pid_t pid);
|
||||||
|
|
||||||
|
@ -598,3 +598,50 @@ meta_log (const char *format, ...)
|
|||||||
g_logv (G_LOG_DOMAIN, mutter_log_level, format, args);
|
g_logv (G_LOG_DOMAIN, mutter_log_level, format, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GFileInfo *
|
||||||
|
pid_namespace_file_info (pid_t pid)
|
||||||
|
{
|
||||||
|
char *filename = g_strdup_printf("/proc/%u/ns/pid", pid);
|
||||||
|
GFile *file = g_file_new_for_path(filename);
|
||||||
|
g_free(filename);
|
||||||
|
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
GFileInfo *info = g_file_query_info(file,
|
||||||
|
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "," G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
|
||||||
|
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
|
||||||
|
g_object_unref(file);
|
||||||
|
|
||||||
|
if (info == NULL) {
|
||||||
|
g_warning("MetaWindow: Error attempting to read /proc/%u/ns/pid symlink: %s", pid, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_file_info_get_is_symlink (info)) {
|
||||||
|
g_warning("MetaWindow: /proc/%u/ns/pid exists but is not a symlink?", pid);
|
||||||
|
g_object_unref (info);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
meta_read_pid_namespace (pid_t pid)
|
||||||
|
{
|
||||||
|
char *value = NULL;
|
||||||
|
GFileInfo *info = pid_namespace_file_info (pid);
|
||||||
|
const char *target = g_file_info_get_symlink_target (info);
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
value = g_strdup (target);
|
||||||
|
}
|
||||||
|
g_object_unref (info);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
@ -549,6 +549,10 @@ struct _MetaWindow
|
|||||||
guint is_alive : 1;
|
guint is_alive : 1;
|
||||||
|
|
||||||
guint in_workspace_change : 1;
|
guint in_workspace_change : 1;
|
||||||
|
|
||||||
|
guint namespace_set: 1;
|
||||||
|
gchar *namespace;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaWindowClass
|
struct _MetaWindowClass
|
||||||
|
@ -348,6 +348,7 @@ meta_window_finalize (GObject *object)
|
|||||||
g_free (window->gtk_app_menu_object_path);
|
g_free (window->gtk_app_menu_object_path);
|
||||||
g_free (window->gtk_menubar_object_path);
|
g_free (window->gtk_menubar_object_path);
|
||||||
g_free (window->placement.rule);
|
g_free (window->placement.rule);
|
||||||
|
g_free (window->namespace);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_window_parent_class)->finalize (object);
|
G_OBJECT_CLASS (meta_window_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -1543,7 +1544,7 @@ meta_window_unmanage (MetaWindow *window,
|
|||||||
g_assert (window->workspace == NULL);
|
g_assert (window->workspace == NULL);
|
||||||
|
|
||||||
#ifndef G_DISABLE_CHECKS
|
#ifndef G_DISABLE_CHECKS
|
||||||
tmp = workspace_manager->workspaces;
|
tmp = workspace_manager->all_workspaces;
|
||||||
while (tmp != NULL)
|
while (tmp != NULL)
|
||||||
{
|
{
|
||||||
MetaWorkspace *workspace = tmp->data;
|
MetaWorkspace *workspace = tmp->data;
|
||||||
@ -4753,7 +4754,7 @@ set_workspace_state (MetaWindow *window,
|
|||||||
else if (window->on_all_workspaces)
|
else if (window->on_all_workspaces)
|
||||||
{
|
{
|
||||||
GList *l;
|
GList *l;
|
||||||
for (l = workspace_manager->workspaces; l != NULL; l = l->next)
|
for (l = workspace_manager->all_workspaces; l != NULL; l = l->next)
|
||||||
{
|
{
|
||||||
MetaWorkspace *ws = l->data;
|
MetaWorkspace *ws = l->data;
|
||||||
meta_workspace_remove_window (ws, window);
|
meta_workspace_remove_window (ws, window);
|
||||||
@ -4768,7 +4769,7 @@ set_workspace_state (MetaWindow *window,
|
|||||||
else if (window->on_all_workspaces)
|
else if (window->on_all_workspaces)
|
||||||
{
|
{
|
||||||
GList *l;
|
GList *l;
|
||||||
for (l = workspace_manager->workspaces; l != NULL; l = l->next)
|
for (l = workspace_manager->all_workspaces; l != NULL; l = l->next)
|
||||||
{
|
{
|
||||||
MetaWorkspace *ws = l->data;
|
MetaWorkspace *ws = l->data;
|
||||||
meta_workspace_add_window (ws, window);
|
meta_workspace_add_window (ws, window);
|
||||||
@ -5140,8 +5141,10 @@ meta_window_change_workspace_by_index (MetaWindow *window,
|
|||||||
workspace =
|
workspace =
|
||||||
meta_workspace_manager_get_workspace_by_index (workspace_manager, space_index);
|
meta_workspace_manager_get_workspace_by_index (workspace_manager, space_index);
|
||||||
|
|
||||||
if (!workspace && append)
|
if (!workspace && append) {
|
||||||
workspace = meta_workspace_manager_append_new_workspace (workspace_manager, FALSE, META_CURRENT_TIME);
|
workspace = meta_workspace_manager_append_new_workspace (workspace_manager, FALSE, META_CURRENT_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (workspace)
|
if (workspace)
|
||||||
meta_window_change_workspace (window, workspace);
|
meta_window_change_workspace (window, workspace);
|
||||||
@ -5396,7 +5399,7 @@ meta_window_get_workspaces (MetaWindow *window)
|
|||||||
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
|
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
|
||||||
|
|
||||||
if (window->on_all_workspaces)
|
if (window->on_all_workspaces)
|
||||||
return workspace_manager->workspaces;
|
return workspace_manager->all_workspaces;
|
||||||
else if (window->workspace != NULL)
|
else if (window->workspace != NULL)
|
||||||
return window->workspace->list_containing_self;
|
return window->workspace->list_containing_self;
|
||||||
else if (window->constructing)
|
else if (window->constructing)
|
||||||
@ -8010,3 +8013,32 @@ meta_get_window_suspend_timeout_s (void)
|
|||||||
{
|
{
|
||||||
return SUSPEND_HIDDEN_TIMEOUT_S;
|
return SUSPEND_HIDDEN_TIMEOUT_S;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_window_namespace:
|
||||||
|
* @window: a #MetaWindow
|
||||||
|
*
|
||||||
|
* Returns string identifying PID namespace this window belongs to
|
||||||
|
* if known
|
||||||
|
*
|
||||||
|
* Return value: (transfer none): the pid namespace string, or %NULL
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
meta_window_namespace (MetaWindow *window)
|
||||||
|
{
|
||||||
|
if (!window->namespace_set) {
|
||||||
|
window->namespace_set = TRUE;
|
||||||
|
pid_t pid = meta_window_get_pid (window);
|
||||||
|
if (pid) {
|
||||||
|
window->namespace = meta_read_pid_namespace (pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return window->namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_window_is_on_foreign_workspace_context (MetaWindow *window)
|
||||||
|
{
|
||||||
|
return meta_workspace_manager_is_window_on_foreign_context (window->display->workspace_manager, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ struct _MetaWorkspace
|
|||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
MetaDisplay *display;
|
MetaDisplay *display;
|
||||||
MetaWorkspaceManager *manager;
|
MetaWorkspaceManager *manager;
|
||||||
|
guint context_id;
|
||||||
|
|
||||||
GList *windows;
|
GList *windows;
|
||||||
|
|
||||||
@ -73,6 +74,8 @@ struct _MetaWorkspaceClass
|
|||||||
};
|
};
|
||||||
|
|
||||||
MetaWorkspace* meta_workspace_new (MetaWorkspaceManager *workspace_manager);
|
MetaWorkspace* meta_workspace_new (MetaWorkspaceManager *workspace_manager);
|
||||||
|
MetaWorkspace* meta_workspace_new_with_context_id (MetaWorkspaceManager *workspace_manager,
|
||||||
|
guint context_id);
|
||||||
void meta_workspace_remove (MetaWorkspace *workspace);
|
void meta_workspace_remove (MetaWorkspace *workspace);
|
||||||
void meta_workspace_add_window (MetaWorkspace *workspace,
|
void meta_workspace_add_window (MetaWorkspace *workspace,
|
||||||
MetaWindow *window);
|
MetaWindow *window);
|
||||||
|
@ -210,7 +210,7 @@ meta_workspace_init (MetaWorkspace *workspace)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MetaWorkspace *
|
MetaWorkspace *
|
||||||
meta_workspace_new (MetaWorkspaceManager *workspace_manager)
|
meta_workspace_new_with_context_id (MetaWorkspaceManager *workspace_manager, guint context_id)
|
||||||
{
|
{
|
||||||
MetaDisplay *display = workspace_manager->display;
|
MetaDisplay *display = workspace_manager->display;
|
||||||
MetaWorkspace *workspace;
|
MetaWorkspace *workspace;
|
||||||
@ -220,9 +220,11 @@ meta_workspace_new (MetaWorkspaceManager *workspace_manager)
|
|||||||
|
|
||||||
workspace->display = display;
|
workspace->display = display;
|
||||||
workspace->manager = workspace_manager;
|
workspace->manager = workspace_manager;
|
||||||
|
workspace->context_id = context_id;
|
||||||
|
|
||||||
|
workspace_manager->all_workspaces =
|
||||||
|
g_list_append (workspace_manager->all_workspaces, workspace);
|
||||||
|
|
||||||
workspace_manager->workspaces =
|
|
||||||
g_list_append (workspace_manager->workspaces, workspace);
|
|
||||||
workspace->windows = NULL;
|
workspace->windows = NULL;
|
||||||
workspace->mru_list = NULL;
|
workspace->mru_list = NULL;
|
||||||
|
|
||||||
@ -249,9 +251,17 @@ meta_workspace_new (MetaWorkspaceManager *workspace_manager)
|
|||||||
meta_workspace_add_window (workspace, l->data);
|
meta_workspace_add_window (workspace, l->data);
|
||||||
g_slist_free (windows);
|
g_slist_free (windows);
|
||||||
|
|
||||||
|
meta_workspace_manager_append_context_workspace (workspace_manager, workspace);
|
||||||
|
|
||||||
return workspace;
|
return workspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaWorkspace *
|
||||||
|
meta_workspace_new (MetaWorkspaceManager *workspace_manager)
|
||||||
|
{
|
||||||
|
return meta_workspace_new_with_context_id (workspace_manager, workspace_manager->active_context->id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* workspace_free_all_struts:
|
* workspace_free_all_struts:
|
||||||
* @workspace: The workspace.
|
* @workspace: The workspace.
|
||||||
@ -306,8 +316,7 @@ meta_workspace_remove (MetaWorkspace *workspace)
|
|||||||
|
|
||||||
assert_workspace_empty (workspace);
|
assert_workspace_empty (workspace);
|
||||||
|
|
||||||
manager->workspaces =
|
meta_workspace_manager_remove_context_workspace (manager, workspace);
|
||||||
g_list_remove (manager->workspaces, workspace);
|
|
||||||
|
|
||||||
meta_workspace_clear_logical_monitor_data (workspace);
|
meta_workspace_clear_logical_monitor_data (workspace);
|
||||||
|
|
||||||
@ -376,8 +385,8 @@ meta_workspace_add_window (MetaWorkspace *workspace,
|
|||||||
if (window->struts)
|
if (window->struts)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_WORKAREA,
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
"Invalidating work area of workspace %d since we're adding window %s to it",
|
"Invalidating work area of workspace %08x since we're adding window %s to it",
|
||||||
meta_workspace_index (workspace), window->desc);
|
meta_workspace_get_id (workspace), window->desc);
|
||||||
meta_workspace_invalidate_work_area (workspace);
|
meta_workspace_invalidate_work_area (workspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,8 +414,8 @@ meta_workspace_remove_window (MetaWorkspace *workspace,
|
|||||||
if (window->struts)
|
if (window->struts)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_WORKAREA,
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
"Invalidating work area of workspace %d since we're removing window %s from it",
|
"Invalidating work area of workspace %08x since we're removing window %s from it",
|
||||||
meta_workspace_index (workspace), window->desc);
|
meta_workspace_get_id (workspace), window->desc);
|
||||||
meta_workspace_invalidate_work_area (workspace);
|
meta_workspace_invalidate_work_area (workspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,6 +471,11 @@ workspace_switch_sound (MetaWorkspace *from,
|
|||||||
int x, y;
|
int x, y;
|
||||||
const char *sound_name;
|
const char *sound_name;
|
||||||
|
|
||||||
|
if (from->context_id != to->context_id) {
|
||||||
|
/* XXX: There is no sound for context switches, but there should be (?) */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
n_workspaces = meta_workspace_manager_get_n_workspaces (from->manager);
|
n_workspaces = meta_workspace_manager_get_n_workspaces (from->manager);
|
||||||
from_idx = meta_workspace_index(from);
|
from_idx = meta_workspace_index(from);
|
||||||
to_idx = meta_workspace_index(to);
|
to_idx = meta_workspace_index(to);
|
||||||
@ -546,13 +560,19 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
|||||||
MetaWorkspaceLayout layout1, layout2;
|
MetaWorkspaceLayout layout1, layout2;
|
||||||
gint num_workspaces, current_space, new_space;
|
gint num_workspaces, current_space, new_space;
|
||||||
MetaMotionDirection direction;
|
MetaMotionDirection direction;
|
||||||
|
MetaWorkspaceContext *context;
|
||||||
MetaWindowDrag *window_drag;
|
MetaWindowDrag *window_drag;
|
||||||
|
|
||||||
g_return_if_fail (META_IS_WORKSPACE (workspace));
|
g_return_if_fail (META_IS_WORKSPACE (workspace));
|
||||||
g_return_if_fail (meta_workspace_index (workspace) != -1);
|
g_return_if_fail (meta_workspace_index (workspace) != -1);
|
||||||
|
|
||||||
meta_verbose ("Activating workspace %d",
|
meta_verbose ("Activating workspace %08x",
|
||||||
meta_workspace_index (workspace));
|
meta_workspace_get_id (workspace));
|
||||||
|
|
||||||
|
context = meta_workspace_manager_lookup_context (workspace->manager, workspace->context_id);
|
||||||
|
if(context && !meta_workspace_context_is_current (context)) {
|
||||||
|
meta_workspace_context_make_active (context);
|
||||||
|
}
|
||||||
|
|
||||||
if (workspace->manager->active_workspace == workspace)
|
if (workspace->manager->active_workspace == workspace)
|
||||||
{
|
{
|
||||||
@ -620,52 +640,59 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
|||||||
comp = meta_display_get_compositor (workspace->display);
|
comp = meta_display_get_compositor (workspace->display);
|
||||||
direction = 0;
|
direction = 0;
|
||||||
|
|
||||||
current_space = meta_workspace_index (old);
|
|
||||||
new_space = meta_workspace_index (workspace);
|
|
||||||
num_workspaces = meta_workspace_manager_get_n_workspaces (workspace->manager);
|
|
||||||
meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces,
|
|
||||||
current_space, &layout1);
|
|
||||||
|
|
||||||
meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces,
|
if (workspace->context_id != old->context_id) {
|
||||||
|
direction = META_MOTION_CONTEXT_SWITCH;
|
||||||
|
current_space = meta_workspace_get_id (old);
|
||||||
|
new_space = meta_workspace_get_id (workspace);
|
||||||
|
} else {
|
||||||
|
current_space = meta_workspace_index (old);
|
||||||
|
new_space = meta_workspace_index (workspace);
|
||||||
|
num_workspaces = meta_workspace_manager_get_n_workspaces (workspace->manager);
|
||||||
|
meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces,
|
||||||
|
current_space, &layout1);
|
||||||
|
|
||||||
|
meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces,
|
||||||
new_space, &layout2);
|
new_space, &layout2);
|
||||||
|
|
||||||
if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL)
|
if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL)
|
||||||
{
|
{
|
||||||
if (layout1.current_col > layout2.current_col)
|
if (layout1.current_col > layout2.current_col)
|
||||||
direction = META_MOTION_RIGHT;
|
direction = META_MOTION_RIGHT;
|
||||||
else if (layout1.current_col < layout2.current_col)
|
else if (layout1.current_col < layout2.current_col)
|
||||||
direction = META_MOTION_LEFT;
|
direction = META_MOTION_LEFT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (layout1.current_col < layout2.current_col)
|
if (layout1.current_col < layout2.current_col)
|
||||||
direction = META_MOTION_RIGHT;
|
direction = META_MOTION_RIGHT;
|
||||||
else if (layout1.current_col > layout2.current_col)
|
else if (layout1.current_col > layout2.current_col)
|
||||||
direction = META_MOTION_LEFT;
|
direction = META_MOTION_LEFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layout1.current_row < layout2.current_row)
|
if (layout1.current_row < layout2.current_row)
|
||||||
{
|
{
|
||||||
if (!direction)
|
if (!direction)
|
||||||
direction = META_MOTION_DOWN;
|
direction = META_MOTION_DOWN;
|
||||||
else if (direction == META_MOTION_RIGHT)
|
else if (direction == META_MOTION_RIGHT)
|
||||||
direction = META_MOTION_DOWN_RIGHT;
|
direction = META_MOTION_DOWN_RIGHT;
|
||||||
else
|
else
|
||||||
direction = META_MOTION_DOWN_LEFT;
|
direction = META_MOTION_DOWN_LEFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layout1.current_row > layout2.current_row)
|
if (layout1.current_row > layout2.current_row)
|
||||||
{
|
{
|
||||||
if (!direction)
|
if (!direction)
|
||||||
direction = META_MOTION_UP;
|
direction = META_MOTION_UP;
|
||||||
else if (direction == META_MOTION_RIGHT)
|
else if (direction == META_MOTION_RIGHT)
|
||||||
direction = META_MOTION_UP_RIGHT;
|
direction = META_MOTION_UP_RIGHT;
|
||||||
else
|
else
|
||||||
direction = META_MOTION_UP_LEFT;
|
direction = META_MOTION_UP_LEFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_workspace_manager_free_workspace_layout (&layout1);
|
meta_workspace_manager_free_workspace_layout (&layout1);
|
||||||
meta_workspace_manager_free_workspace_layout (&layout2);
|
meta_workspace_manager_free_workspace_layout (&layout2);
|
||||||
|
}
|
||||||
|
|
||||||
meta_compositor_switch_workspace (comp, old, workspace, direction);
|
meta_compositor_switch_workspace (comp, old, workspace, direction);
|
||||||
|
|
||||||
@ -703,12 +730,19 @@ meta_workspace_activate (MetaWorkspace *workspace,
|
|||||||
int
|
int
|
||||||
meta_workspace_index (MetaWorkspace *workspace)
|
meta_workspace_index (MetaWorkspace *workspace)
|
||||||
{
|
{
|
||||||
int ret;
|
return meta_workspace_manager_context_workspace_index (workspace->manager, workspace);
|
||||||
|
}
|
||||||
|
|
||||||
ret = g_list_index (workspace->manager->workspaces, workspace);
|
int
|
||||||
g_return_val_if_fail (ret >= 0, -1);
|
meta_workspace_get_id (MetaWorkspace *workspace)
|
||||||
|
{
|
||||||
|
return meta_workspace_manager_get_workspace_id (workspace->manager, workspace);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
guint
|
||||||
|
meta_workspace_get_context_id (MetaWorkspace *workspace)
|
||||||
|
{
|
||||||
|
return workspace->context_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -766,14 +800,14 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
|
|||||||
if (workspace->work_areas_invalid)
|
if (workspace->work_areas_invalid)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_WORKAREA,
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
"Work area for workspace %d is already invalid",
|
"Work area for workspace %08x is already invalid",
|
||||||
meta_workspace_index (workspace));
|
meta_workspace_get_id (workspace));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_topic (META_DEBUG_WORKAREA,
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
"Invalidating work area for workspace %d",
|
"Invalidating work area for workspace %08x",
|
||||||
meta_workspace_index (workspace));
|
meta_workspace_get_id (workspace));
|
||||||
|
|
||||||
window_drag =
|
window_drag =
|
||||||
meta_compositor_get_current_window_drag (workspace->display->compositor);
|
meta_compositor_get_current_window_drag (workspace->display->compositor);
|
||||||
@ -949,8 +983,8 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
|
|||||||
}
|
}
|
||||||
workspace->work_area_screen = work_area;
|
workspace->work_area_screen = work_area;
|
||||||
meta_topic (META_DEBUG_WORKAREA,
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
"Computed work area for workspace %d: %d,%d %d x %d",
|
"Computed work area for workspace %08x: %d,%d %d x %d",
|
||||||
meta_workspace_index (workspace),
|
meta_workspace_get_id (workspace),
|
||||||
workspace->work_area_screen.x,
|
workspace->work_area_screen.x,
|
||||||
workspace->work_area_screen.y,
|
workspace->work_area_screen.y,
|
||||||
workspace->work_area_screen.width,
|
workspace->work_area_screen.width,
|
||||||
@ -980,8 +1014,8 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
|
|||||||
|
|
||||||
meta_topic (META_DEBUG_WORKAREA,
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
"Computed work area for workspace %d "
|
"Computed work area for workspace %d "
|
||||||
"monitor %d: %d,%d %d x %d",
|
"monitor %08x: %d,%d %d x %d",
|
||||||
meta_workspace_index (workspace),
|
meta_workspace_get_id (workspace),
|
||||||
logical_monitor->number,
|
logical_monitor->number,
|
||||||
data->logical_monitor_work_area.x,
|
data->logical_monitor_work_area.x,
|
||||||
data->logical_monitor_work_area.y,
|
data->logical_monitor_work_area.y,
|
||||||
@ -1225,6 +1259,8 @@ meta_motion_direction_to_string (MetaMotionDirection direction)
|
|||||||
return "Up-Left";
|
return "Up-Left";
|
||||||
case META_MOTION_DOWN_LEFT:
|
case META_MOTION_DOWN_LEFT:
|
||||||
return "Down-Left";
|
return "Down-Left";
|
||||||
|
case META_MOTION_CONTEXT_SWITCH:
|
||||||
|
return "Switch-Context";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
|
@ -258,6 +258,7 @@ typedef enum
|
|||||||
* @META_MOTION_UP_RIGHT: Motion up and to the right
|
* @META_MOTION_UP_RIGHT: Motion up and to the right
|
||||||
* @META_MOTION_DOWN_LEFT: Motion down and to the left
|
* @META_MOTION_DOWN_LEFT: Motion down and to the left
|
||||||
* @META_MOTION_DOWN_RIGHT: Motion down and to the right
|
* @META_MOTION_DOWN_RIGHT: Motion down and to the right
|
||||||
|
* @META_MOTION_CONTEXT_SWITCH: Workspace switch is a change of current realm
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Negative to avoid conflicting with real workspace
|
/* Negative to avoid conflicting with real workspace
|
||||||
@ -273,7 +274,8 @@ typedef enum
|
|||||||
META_MOTION_UP_LEFT = -5,
|
META_MOTION_UP_LEFT = -5,
|
||||||
META_MOTION_UP_RIGHT = -6,
|
META_MOTION_UP_RIGHT = -6,
|
||||||
META_MOTION_DOWN_LEFT = -7,
|
META_MOTION_DOWN_LEFT = -7,
|
||||||
META_MOTION_DOWN_RIGHT = -8
|
META_MOTION_DOWN_RIGHT = -8,
|
||||||
|
META_MOTION_CONTEXT_SWITCH = -9,
|
||||||
} MetaMotionDirection;
|
} MetaMotionDirection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,6 +29,14 @@
|
|||||||
#include <meta/prefs.h>
|
#include <meta/prefs.h>
|
||||||
#include <meta/types.h>
|
#include <meta/types.h>
|
||||||
|
|
||||||
|
#define META_TYPE_WORKSPACE_CONTEXT (meta_workspace_context_get_type ())
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaWorkspaceContext,
|
||||||
|
meta_workspace_context,
|
||||||
|
META, WORKSPACE_CONTEXT,
|
||||||
|
GObject)
|
||||||
|
|
||||||
#define META_TYPE_WORKSPACE_MANAGER (meta_workspace_manager_get_type ())
|
#define META_TYPE_WORKSPACE_MANAGER (meta_workspace_manager_get_type ())
|
||||||
|
|
||||||
META_EXPORT
|
META_EXPORT
|
||||||
@ -65,6 +73,9 @@ void meta_workspace_manager_reorder_workspace (MetaWorkspaceManager *workspace_m
|
|||||||
META_EXPORT
|
META_EXPORT
|
||||||
int meta_workspace_manager_get_active_workspace_index (MetaWorkspaceManager *workspace_manager);
|
int meta_workspace_manager_get_active_workspace_index (MetaWorkspaceManager *workspace_manager);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
int meta_workspace_manager_get_active_workspace_id (MetaWorkspaceManager *workspace_manager);
|
||||||
|
|
||||||
META_EXPORT
|
META_EXPORT
|
||||||
MetaWorkspace *meta_workspace_manager_get_active_workspace (MetaWorkspaceManager *workspace_manager);
|
MetaWorkspace *meta_workspace_manager_get_active_workspace (MetaWorkspaceManager *workspace_manager);
|
||||||
|
|
||||||
@ -74,3 +85,35 @@ void meta_workspace_manager_override_workspace_layout (MetaWorkspaceManager *wor
|
|||||||
gboolean vertical_layout,
|
gboolean vertical_layout,
|
||||||
int n_rows,
|
int n_rows,
|
||||||
int n_columns);
|
int n_columns);
|
||||||
|
META_EXPORT
|
||||||
|
guint meta_workspace_manager_active_context_id (MetaWorkspaceManager *workspace_manager);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
void meta_workspace_manager_set_builtin_struts_all(MetaWorkspaceManager *workspace_manager,
|
||||||
|
GSList *struts);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
MetaWorkspaceContext *meta_workspace_manager_context_for_namespace (MetaWorkspaceManager *workspace_manager,
|
||||||
|
const gchar *namespace);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
const char *meta_workspace_manager_mutter_namespace (MetaWorkspaceManager *workspace_manager);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
void meta_workspace_context_activate (MetaWorkspaceContext *context);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
void meta_workspace_context_remove (MetaWorkspaceContext *context);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
gboolean meta_workspace_context_is_current (MetaWorkspaceContext *context);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
MetaWorkspace *
|
||||||
|
meta_workspace_context_get_active_workspace (MetaWorkspaceContext *context);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
guint meta_workspace_context_id (MetaWorkspaceContext *context);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
void meta_workspace_context_move_window_to_context (MetaWorkspaceContext *context, MetaWindow *window);
|
||||||
|
@ -36,5 +36,6 @@ typedef struct _MetaCursorTracker MetaCursorTracker;
|
|||||||
typedef struct _MetaDnd MetaDnd;
|
typedef struct _MetaDnd MetaDnd;
|
||||||
typedef struct _MetaSettings MetaSettings;
|
typedef struct _MetaSettings MetaSettings;
|
||||||
|
|
||||||
|
typedef struct _MetaWorkspaceContext MetaWorkspaceContext;
|
||||||
typedef struct _MetaWorkspaceManager MetaWorkspaceManager;
|
typedef struct _MetaWorkspaceManager MetaWorkspaceManager;
|
||||||
typedef struct _MetaSelection MetaSelection;
|
typedef struct _MetaSelection MetaSelection;
|
||||||
|
@ -446,3 +446,10 @@ MetaWindowClientType meta_window_get_client_type (MetaWindow *window);
|
|||||||
|
|
||||||
META_EXPORT
|
META_EXPORT
|
||||||
gboolean meta_window_has_pointer (MetaWindow *window);
|
gboolean meta_window_has_pointer (MetaWindow *window);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
const char *meta_window_namespace (MetaWindow *window);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
gboolean meta_window_is_on_foreign_workspace_context (MetaWindow *window);
|
||||||
|
|
||||||
|
@ -38,6 +38,12 @@ GType meta_workspace_get_type (void);
|
|||||||
META_EXPORT
|
META_EXPORT
|
||||||
int meta_workspace_index (MetaWorkspace *workspace);
|
int meta_workspace_index (MetaWorkspace *workspace);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
int meta_workspace_get_id (MetaWorkspace *workspace);
|
||||||
|
|
||||||
|
META_EXPORT
|
||||||
|
guint meta_workspace_get_context_id (MetaWorkspace *workspace);
|
||||||
|
|
||||||
META_EXPORT
|
META_EXPORT
|
||||||
MetaDisplay *meta_workspace_get_display (MetaWorkspace *workspace);
|
MetaDisplay *meta_workspace_get_display (MetaWorkspace *workspace);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user