Live previews for hidden windows.
ClutterActors for hidden windows (such windows on different than active workspaces and windows that are minimized) are available, and reflect the actual state of the window. This is intended for use in task-switchers etc. This feature is disabled by default (due to increased demand on resources), and can be enabled through the metacity/general/live_hidden_windows gconf key. A trivial sample window switcher is included in the scratch plugin (activated by clicking on the slide out panel).
This commit is contained in:
parent
273d213509
commit
07c1003905
@ -112,6 +112,8 @@ metacity_SOURCES += \
|
||||
compositor/mutter/mutter-plugin-manager.h \
|
||||
compositor/mutter/tidy/tidy-texture-frame.c \
|
||||
compositor/mutter/tidy/tidy-texture-frame.h \
|
||||
compositor/mutter/tidy/tidy-grid.c \
|
||||
compositor/mutter/tidy/tidy-grid.h \
|
||||
include/mutter-plugin.h
|
||||
endif
|
||||
|
||||
|
@ -78,6 +78,9 @@ struct _MetaCompositor
|
||||
MetaWorkspace *from,
|
||||
MetaWorkspace *to,
|
||||
MetaMotionDirection direction);
|
||||
|
||||
void (*ensure_stack_order) (MetaCompositor *compositor,
|
||||
MetaScreen *screen);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -242,3 +242,12 @@ meta_compositor_switch_workspace (MetaCompositor *compositor,
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_ensure_stack_order (MetaCompositor *compositor,
|
||||
MetaScreen *screen)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->ensure_stack_order)
|
||||
compositor->ensure_stack_order (compositor, screen);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _XOPEN_SOURCE 500 /* for usleep() */
|
||||
|
||||
@ -10,6 +12,7 @@
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "../../core/window-private.h"
|
||||
#include "display.h"
|
||||
#include "screen.h"
|
||||
#include "frame.h"
|
||||
@ -20,6 +23,7 @@
|
||||
#include "mutter-plugin-manager.h"
|
||||
#include "tidy/tidy-texture-frame.h"
|
||||
#include "xprops.h"
|
||||
#include "prefs.h"
|
||||
#include "mutter-shaped-texture.h"
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xlibint.h>
|
||||
@ -46,6 +50,16 @@
|
||||
#define TILE_WIDTH (3*MAX_TILE_SZ)
|
||||
#define TILE_HEIGHT (3*MAX_TILE_SZ)
|
||||
|
||||
#define CHECK_LIST_INTEGRITY_START(list) \
|
||||
{int len2__; int len__ = g_list_length(list);
|
||||
|
||||
#define CHECK_LIST_INTEGRITY_END(list) \
|
||||
len2__ = g_list_length(list); \
|
||||
if (len__ != len2__) \
|
||||
g_warning ("Integrity check of list failed at %s:%d\n", \
|
||||
__FILE__, __LINE__); }
|
||||
|
||||
|
||||
/*
|
||||
* Register GType wrapper for XWindowAttributes, so we do not have to
|
||||
* query window attributes in the MutterWindow constructor but can pass
|
||||
@ -447,7 +461,7 @@ find_window_for_screen (MetaScreen *screen, Window xwindow)
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
if (info == NULL)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
return g_hash_table_lookup (info->windows_by_xid, (gpointer) xwindow);
|
||||
}
|
||||
@ -690,6 +704,18 @@ mutter_window_get_x_window (MutterWindow *mcw)
|
||||
return mcw->priv->xwindow;
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
mutter_window_get_meta_window (MutterWindow *mcw)
|
||||
{
|
||||
return mcw->priv->window;
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
mutter_window_get_texture (MutterWindow *mcw)
|
||||
{
|
||||
return mcw->priv->actor;
|
||||
}
|
||||
|
||||
MetaCompWindowType
|
||||
mutter_window_get_window_type (MutterWindow *mcw)
|
||||
{
|
||||
@ -699,6 +725,15 @@ mutter_window_get_window_type (MutterWindow *mcw)
|
||||
return mcw->priv->type;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mutter_window_is_override_redirect (MutterWindow *mcw)
|
||||
{
|
||||
if (!mcw->priv->window)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gint
|
||||
mutter_window_get_workspace (MutterWindow *mcw)
|
||||
{
|
||||
@ -718,6 +753,23 @@ mutter_window_get_workspace (MutterWindow *mcw)
|
||||
return meta_workspace_index (workspace);
|
||||
}
|
||||
|
||||
gboolean
|
||||
mutter_window_is_hidden (MutterWindow *mcw)
|
||||
{
|
||||
MutterWindowPrivate *priv;
|
||||
|
||||
if (!mcw)
|
||||
return TRUE;
|
||||
|
||||
priv = mcw->priv;
|
||||
|
||||
if (!priv->window)
|
||||
return FALSE;
|
||||
|
||||
return meta_window_is_hidden (priv->window);
|
||||
}
|
||||
|
||||
|
||||
static void repair_win (MutterWindow *cw);
|
||||
static void map_win (MutterWindow *cw);
|
||||
static void unmap_win (MutterWindow *cw);
|
||||
@ -726,54 +778,83 @@ static void
|
||||
mutter_finish_workspace_switch (MetaCompScreen *info)
|
||||
{
|
||||
GList *last = g_list_last (info->windows);
|
||||
GList *l = last;
|
||||
GList *l;
|
||||
|
||||
/* printf ("FINISHING DESKTOP SWITCH\n"); */
|
||||
|
||||
if (!meta_prefs_get_live_hidden_windows ())
|
||||
{
|
||||
/* When running in the traditional mode where hidden windows get
|
||||
* unmapped, we need to fix up the map status for each window, since
|
||||
* we are ignoring unmap requests during the effect.
|
||||
*/
|
||||
l = last;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MutterWindow *cw = l->data;
|
||||
MutterWindowPrivate *priv = cw->priv;
|
||||
|
||||
if (priv->needs_map && !priv->needs_unmap)
|
||||
{
|
||||
map_win (cw);
|
||||
}
|
||||
|
||||
if (priv->needs_unmap)
|
||||
{
|
||||
unmap_win (cw);
|
||||
}
|
||||
|
||||
l = l->prev;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix up stacking order in case the plugin messed it up.
|
||||
*/
|
||||
l = last;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MutterWindow *cw = l->data;
|
||||
MutterWindowPrivate *priv = cw->priv;
|
||||
ClutterActor *a = l->data;
|
||||
MutterWindow *mw = l->data;
|
||||
MetaWindow *window = mw->priv->window;
|
||||
|
||||
if (priv->needs_map && !priv->needs_unmap)
|
||||
/*
|
||||
* If this window is not marked as hidden, we raise it.
|
||||
* If it has no MetaWindow associated (i.e., override redirect), we
|
||||
* raise it too. Everything else we push to the bottom.
|
||||
*/
|
||||
if (!window || !meta_window_is_hidden (window))
|
||||
{
|
||||
map_win (cw);
|
||||
#if 0
|
||||
printf ("raising %p [0x%x] (%s) to top\n",
|
||||
a,
|
||||
(guint)mw->priv->xwindow,
|
||||
mw->priv->window ? mw->priv->window->desc : "unknown");
|
||||
#endif
|
||||
clutter_actor_raise_top (a);
|
||||
}
|
||||
|
||||
if (priv->needs_unmap)
|
||||
else
|
||||
{
|
||||
unmap_win (cw);
|
||||
#if 0
|
||||
printf ("lowering %p [0x%x] (%s) to bottom\n",
|
||||
a,
|
||||
(guint)mw->priv->xwindow,
|
||||
mw->priv->window ? mw->priv->window->desc : "unknown");
|
||||
#endif
|
||||
clutter_actor_lower_bottom (a);
|
||||
}
|
||||
|
||||
l = l->prev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now fix up stacking order in case the plugin messed it up.
|
||||
*/
|
||||
l = last;
|
||||
while (l)
|
||||
{
|
||||
ClutterActor *a = l->data;
|
||||
GList *prev = l->prev;
|
||||
/* printf ("... FINISHED DESKTOP SWITCH\n"); */
|
||||
|
||||
if (prev)
|
||||
{
|
||||
ClutterActor *above_me = prev->data;
|
||||
|
||||
clutter_actor_raise (above_me, a);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClutterActor *a = l->data;
|
||||
clutter_actor_raise_top (a);
|
||||
}
|
||||
|
||||
l = prev;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mutter_window_effect_completed (MutterWindow *cw,
|
||||
gulong event)
|
||||
mutter_window_effect_completed (MutterWindow *cw, gulong event)
|
||||
{
|
||||
MutterWindowPrivate *priv = cw->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
@ -784,8 +865,7 @@ mutter_window_effect_completed (MutterWindow *cw,
|
||||
{
|
||||
case MUTTER_PLUGIN_MINIMIZE:
|
||||
{
|
||||
ClutterActor *a = CLUTTER_ACTOR (cw);
|
||||
gint height = clutter_actor_get_height (a);
|
||||
ClutterActor *a = CLUTTER_ACTOR (cw);
|
||||
|
||||
priv->minimize_in_progress--;
|
||||
if (priv->minimize_in_progress < 0)
|
||||
@ -797,7 +877,19 @@ mutter_window_effect_completed (MutterWindow *cw,
|
||||
if (!priv->minimize_in_progress)
|
||||
{
|
||||
priv->is_minimized = TRUE;
|
||||
clutter_actor_set_position (a, 0, -height);
|
||||
|
||||
/*
|
||||
* We must ensure that the minimized actor is pushed down the stack
|
||||
* (the XConfigureEvent has 'above' semantics, i.e., when a window
|
||||
* is lowered, we get a bunch of 'raise' notifications, but might
|
||||
* not get any notification for the window that has been lowered.
|
||||
*/
|
||||
clutter_actor_lower_bottom (a);
|
||||
|
||||
/* Make sure that after the effect finishes, the actor is
|
||||
* made visible for sake of live previews.
|
||||
*/
|
||||
clutter_actor_show (a);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -911,16 +1003,51 @@ mutter_window_detach (MutterWindow *self)
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_win (MetaDisplay *display, Window xwindow)
|
||||
destroy_win (MutterWindow *cw, gboolean no_effect)
|
||||
{
|
||||
MutterWindow *cw;
|
||||
MetaCompScreen *info;
|
||||
MutterWindowPrivate *priv;
|
||||
MetaScreen *screen;
|
||||
|
||||
cw = find_window_in_display (display, xwindow);
|
||||
|
||||
if (cw == NULL)
|
||||
if (!cw)
|
||||
return;
|
||||
|
||||
clutter_actor_destroy (CLUTTER_ACTOR (cw));
|
||||
priv = cw->priv;
|
||||
|
||||
screen = priv->screen;
|
||||
info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
|
||||
/*
|
||||
* We remove the window from internal lookup hashes and thus any other
|
||||
* unmap events etc fail
|
||||
*/
|
||||
info->windows = g_list_remove (info->windows, (gconstpointer) cw);
|
||||
g_hash_table_remove (info->windows_by_xid, (gpointer)priv->xwindow);
|
||||
|
||||
if (no_effect || priv->type == META_COMP_WINDOW_OVERRIDE)
|
||||
{
|
||||
/*
|
||||
* No effects, just kill it.
|
||||
*/
|
||||
clutter_actor_destroy (CLUTTER_ACTOR (cw));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a plugin manager is present, try to run an effect; if no effect of this
|
||||
* type is present, destroy the actor.
|
||||
*/
|
||||
priv->destroy_in_progress++;
|
||||
|
||||
if (!info->plugin_mgr ||
|
||||
!mutter_plugin_manager_event_simple (info->plugin_mgr,
|
||||
cw,
|
||||
MUTTER_PLUGIN_DESTROY))
|
||||
{
|
||||
priv->destroy_in_progress--;
|
||||
clutter_actor_destroy (CLUTTER_ACTOR (cw));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -931,6 +1058,13 @@ restack_win (MutterWindow *cw, Window above)
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
Window previous_above;
|
||||
GList *sibling, *next;
|
||||
gboolean hide = FALSE;
|
||||
gboolean live_mode;
|
||||
|
||||
live_mode = meta_prefs_get_live_hidden_windows ();
|
||||
|
||||
if (priv->window && meta_window_is_hidden (priv->window))
|
||||
hide = TRUE;
|
||||
|
||||
sibling = g_list_find (info->windows, (gconstpointer) cw);
|
||||
next = g_list_next (sibling);
|
||||
@ -947,45 +1081,135 @@ restack_win (MutterWindow *cw, Window above)
|
||||
*/
|
||||
if (above == None)
|
||||
{
|
||||
#if 0
|
||||
printf ("Raising to top %p [0x%x] (%s)\n",
|
||||
cw, (guint) priv->xwindow,
|
||||
priv->window ? priv->window->desc : "unknown");
|
||||
#endif
|
||||
/* Insert at bottom of window stack */
|
||||
CHECK_LIST_INTEGRITY_START(info->windows)
|
||||
info->windows = g_list_delete_link (info->windows, sibling);
|
||||
info->windows = g_list_append (info->windows, cw);
|
||||
CHECK_LIST_INTEGRITY_END(info->windows)
|
||||
|
||||
if (!info->switch_workspace_in_progress)
|
||||
clutter_actor_raise_top (CLUTTER_ACTOR (cw));
|
||||
{
|
||||
clutter_actor_raise_top (CLUTTER_ACTOR (cw));
|
||||
}
|
||||
}
|
||||
else if (previous_above != above)
|
||||
{
|
||||
GList *index;
|
||||
|
||||
for (index = info->windows; index; index = index->next)
|
||||
/* Find the window that matches 'above'; if the window is hidden (i.e.,
|
||||
* minimized, on a different desktop) find the first window above it tha
|
||||
* is not and use it instead; if we cannot find any such window then
|
||||
* fallback to raise to top (without this, we end up stacking up the act
|
||||
* in the wrong place, and it probably will not be visible at all).
|
||||
*/
|
||||
for (index = info->windows; index; index = index->next)
|
||||
{
|
||||
MutterWindow *cw2 = (MutterWindow *) index->data;
|
||||
if (cw2->priv->xwindow == above)
|
||||
break;
|
||||
{
|
||||
if (live_mode && !hide && cw2->priv->window &&
|
||||
meta_window_is_hidden (cw2->priv->window))
|
||||
{
|
||||
index = index->prev;
|
||||
|
||||
while (index)
|
||||
{
|
||||
MutterWindow *prev = index->data;
|
||||
|
||||
if (!prev->priv->window ||
|
||||
!meta_window_is_hidden (prev->priv->window))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
index = index->prev;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index != NULL)
|
||||
{
|
||||
ClutterActor *above_win = index->data;
|
||||
if (index != sibling)
|
||||
{
|
||||
ClutterActor *above_win = index->data;
|
||||
MutterWindow *cw2 = index->data;
|
||||
|
||||
info->windows = g_list_delete_link (info->windows, sibling);
|
||||
info->windows = g_list_insert_before (info->windows, index, cw);
|
||||
CHECK_LIST_INTEGRITY_START(info->windows)
|
||||
info->windows = g_list_delete_link (info->windows, sibling);
|
||||
|
||||
if (!info->switch_workspace_in_progress)
|
||||
clutter_actor_raise (CLUTTER_ACTOR (cw), above_win);
|
||||
info->windows = g_list_insert_before (info->windows, index, cw);
|
||||
CHECK_LIST_INTEGRITY_END(info->windows)
|
||||
|
||||
#if 0
|
||||
printf ("Raising %p [0x%x] (%s) hidden %d, above %p [0x%x] (%s)\n",
|
||||
cw, (guint) priv->xwindow,
|
||||
priv->window ? priv->window->desc : "unknown", hide,
|
||||
cw2, (guint) cw2->priv->xwindow,
|
||||
cw2->priv->window ? cw2->priv->window->desc : "unknown");
|
||||
#endif
|
||||
if (!info->switch_workspace_in_progress)
|
||||
{
|
||||
clutter_actor_raise (CLUTTER_ACTOR (cw), above_win);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (live_mode)
|
||||
{
|
||||
if (!hide)
|
||||
{
|
||||
#if 0
|
||||
printf ("Raising to top as fallback %p [0x%x] (%s)\n",
|
||||
cw, (guint) priv->xwindow,
|
||||
priv->window ? priv->window->desc : "unknown");
|
||||
#endif
|
||||
/* Insert at bottom of window stack */
|
||||
CHECK_LIST_INTEGRITY_START(info->windows)
|
||||
info->windows = g_list_delete_link (info->windows, sibling);
|
||||
info->windows = g_list_append (info->windows, cw);
|
||||
CHECK_LIST_INTEGRITY_END(info->windows)
|
||||
|
||||
if (!info->switch_workspace_in_progress)
|
||||
{
|
||||
clutter_actor_raise_top (CLUTTER_ACTOR (cw));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
printf ("Lowering to bottom as fallback %p [0x%x] (%s)\n",
|
||||
cw, (guint) priv->xwindow,
|
||||
priv->window ? priv->window->desc : "unknown");
|
||||
#endif
|
||||
/* Insert at bottom of window stack */
|
||||
CHECK_LIST_INTEGRITY_START(info->windows)
|
||||
info->windows = g_list_delete_link (info->windows, sibling);
|
||||
info->windows = g_list_prepend (info->windows, cw);
|
||||
CHECK_LIST_INTEGRITY_END(info->windows)
|
||||
|
||||
if (!info->switch_workspace_in_progress)
|
||||
{
|
||||
clutter_actor_lower_bottom (CLUTTER_ACTOR (cw));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
resize_win (MutterWindow *cw,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int border_width,
|
||||
gboolean override_redirect)
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int border_width,
|
||||
gboolean override_redirect)
|
||||
{
|
||||
MutterWindowPrivate *priv = cw->priv;
|
||||
|
||||
@ -1093,15 +1317,15 @@ unmap_win (MutterWindow *cw)
|
||||
}
|
||||
|
||||
priv->attrs.map_state = IsUnmapped;
|
||||
|
||||
if (!priv->minimize_in_progress)
|
||||
{
|
||||
ClutterActor *a = CLUTTER_ACTOR (cw);
|
||||
clutter_actor_hide (a);
|
||||
}
|
||||
|
||||
priv->needs_unmap = FALSE;
|
||||
priv->needs_map = FALSE;
|
||||
|
||||
if (!priv->minimize_in_progress &&
|
||||
(!meta_prefs_get_live_hidden_windows () ||
|
||||
priv->type == META_COMP_WINDOW_OVERRIDE))
|
||||
{
|
||||
clutter_actor_hide (CLUTTER_ACTOR (cw));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1114,6 +1338,7 @@ add_win (MetaScreen *screen, MetaWindow *window, Window xwindow)
|
||||
MutterWindowPrivate *priv;
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
XWindowAttributes attrs;
|
||||
gulong events_needed;
|
||||
|
||||
if (info == NULL)
|
||||
return;
|
||||
@ -1122,17 +1347,19 @@ add_win (MetaScreen *screen, MetaWindow *window, Window xwindow)
|
||||
return;
|
||||
|
||||
if (!XGetWindowAttributes (xdisplay, xwindow, &attrs))
|
||||
return;
|
||||
return;
|
||||
|
||||
/*
|
||||
* If Metacity has decided not to manage this window then the input events
|
||||
* won't have been set on the window
|
||||
*/
|
||||
if (!(attrs.your_event_mask & PropertyChangeMask))
|
||||
events_needed = PropertyChangeMask | SubstructureNotifyMask;
|
||||
|
||||
if (!(attrs.your_event_mask & PropertyChangeMask) ||
|
||||
!(attrs.your_event_mask & SubstructureNotifyMask))
|
||||
{
|
||||
gulong event_mask;
|
||||
|
||||
event_mask = attrs.your_event_mask | PropertyChangeMask;
|
||||
event_mask = attrs.your_event_mask | events_needed;
|
||||
XSelectInput (xdisplay, xwindow, event_mask);
|
||||
}
|
||||
|
||||
@ -1159,8 +1386,8 @@ add_win (MetaScreen *screen, MetaWindow *window, Window xwindow)
|
||||
info->dock_windows = g_slist_append (info->dock_windows, cw);
|
||||
}
|
||||
|
||||
meta_verbose ("added 0x%x (%p) type:", (guint)xwindow, cw);
|
||||
#if 0
|
||||
printf ("added 0x%x (%p) type:", (guint)xwindow, cw);
|
||||
|
||||
switch (cw->type)
|
||||
{
|
||||
@ -1335,8 +1562,8 @@ process_create (Mutter *compositor,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaScreen *screen;
|
||||
MutterWindow *cw;
|
||||
Window xwindow = event->window;
|
||||
MutterWindow *mw;
|
||||
|
||||
screen = meta_display_screen_for_root (compositor->display, event->parent);
|
||||
|
||||
@ -1347,18 +1574,18 @@ process_create (Mutter *compositor,
|
||||
* This is quite silly as we end up creating windows as then immediatly
|
||||
* destroying them as they (likely) become framed and thus reparented.
|
||||
*/
|
||||
cw = find_window_for_screen (screen, event->window);
|
||||
mw = find_window_for_screen (screen, xwindow);
|
||||
|
||||
if (!cw && window)
|
||||
if (!mw && window)
|
||||
{
|
||||
xwindow = meta_window_get_xwindow (window);
|
||||
|
||||
cw = find_window_for_screen (screen, xwindow);
|
||||
mw = find_window_for_screen (screen, xwindow);
|
||||
}
|
||||
|
||||
if (cw)
|
||||
if (mw)
|
||||
{
|
||||
destroy_win (compositor->display, xwindow);
|
||||
destroy_win (mw, TRUE);
|
||||
}
|
||||
|
||||
add_win (screen, window, event->window);
|
||||
@ -1369,16 +1596,24 @@ process_reparent (Mutter *compositor,
|
||||
XReparentEvent *event,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaScreen *screen;
|
||||
MetaScreen *screen;
|
||||
MutterWindow *mw;
|
||||
Window xwindow = event->window;
|
||||
gboolean viewable = FALSE;
|
||||
|
||||
screen = meta_display_screen_for_root (compositor->display, event->parent);
|
||||
|
||||
if (!screen)
|
||||
return;
|
||||
|
||||
mw = find_window_for_screen (screen, event->window);
|
||||
mw = find_window_for_screen (screen, xwindow);
|
||||
|
||||
if (!mw && window)
|
||||
{
|
||||
xwindow = meta_window_get_xwindow (window);
|
||||
|
||||
mw = find_window_for_screen (screen, xwindow);
|
||||
}
|
||||
|
||||
if (!mw && window)
|
||||
{
|
||||
@ -1390,19 +1625,23 @@ process_reparent (Mutter *compositor,
|
||||
|
||||
if (mw)
|
||||
{
|
||||
meta_verbose ("reparent: destroying a window 0%x\n",
|
||||
(guint)event->window);
|
||||
destroy_win (compositor->display, xwindow);
|
||||
viewable = (mw->priv->attrs.map_state == IsViewable);
|
||||
destroy_win (mw, TRUE);
|
||||
}
|
||||
|
||||
add_win (screen, window, event->window);
|
||||
}
|
||||
|
||||
static void
|
||||
process_destroy (Mutter *compositor,
|
||||
XDestroyWindowEvent *event)
|
||||
process_destroy (Mutter *compositor, XDestroyWindowEvent *event)
|
||||
{
|
||||
destroy_win (compositor->display, event->window);
|
||||
MutterWindow *cw =
|
||||
find_window_in_display (compositor->display, event->window);
|
||||
|
||||
if (!cw)
|
||||
return;
|
||||
|
||||
destroy_win (cw, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1437,7 +1676,7 @@ process_damage (Mutter *compositor,
|
||||
if (XCheckTypedWindowEvent (dpy, drawable, DestroyNotify, &next))
|
||||
{
|
||||
priv->destroy_pending = TRUE;
|
||||
process_destroy (compositor, (XDestroyWindowEvent *) &next);
|
||||
destroy_win (cw, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1501,7 +1740,18 @@ process_configure_notify (Mutter *compositor,
|
||||
XConfigureEvent *event)
|
||||
{
|
||||
MetaDisplay *display = compositor->display;
|
||||
MutterWindow *cw = find_window_in_display (display, event->window);
|
||||
MutterWindow *cw;
|
||||
|
||||
/*
|
||||
* We get each configure event twice; once through the WM solicitation of the
|
||||
* events on the root window, and once through solicitation on the window
|
||||
* itself -- we will only handle the latter, in which case the event and
|
||||
* window members of the config event are identical.
|
||||
*/
|
||||
if (event->event != event->window)
|
||||
return;
|
||||
|
||||
cw = find_window_in_display (display, event->window);
|
||||
|
||||
if (cw)
|
||||
{
|
||||
@ -1596,25 +1846,28 @@ process_unmap (Mutter *compositor,
|
||||
if (XCheckTypedWindowEvent (dpy, xwin, DestroyNotify, &next))
|
||||
{
|
||||
priv->destroy_pending = TRUE;
|
||||
process_destroy (compositor, (XDestroyWindowEvent *) &next);
|
||||
destroy_win (cw, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
meta_verbose ("processing unmap of 0x%x (%p)\n", (guint)xwin, cw);
|
||||
unmap_win (cw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_map (Mutter *compositor,
|
||||
XMapEvent *event,
|
||||
MetaWindow *window)
|
||||
process_map (Mutter *compositor,
|
||||
XMapEvent *event,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MutterWindow *cw = find_window_in_display (compositor->display,
|
||||
event->window);
|
||||
MutterWindow *cw;
|
||||
Window xwindow = event->window;
|
||||
|
||||
cw = find_window_in_display (compositor->display, xwindow);
|
||||
|
||||
if (cw)
|
||||
map_win (cw);
|
||||
{
|
||||
map_win (cw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1727,6 +1980,16 @@ mutter_get_overlay_group_for_screen (MetaScreen *screen)
|
||||
return info->overlay_group;
|
||||
}
|
||||
|
||||
GList *
|
||||
mutter_get_windows (MetaScreen *screen)
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
return info->windows;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_cmp_manage_screen (MetaCompositor *compositor,
|
||||
@ -1843,6 +2106,7 @@ clutter_cmp_add_window (MetaCompositor *compositor,
|
||||
MetaScreen *screen = meta_screen_for_x_screen (attrs->screen);
|
||||
|
||||
meta_error_trap_push (xrc->display);
|
||||
|
||||
add_win (screen, window, xwindow);
|
||||
meta_error_trap_pop (xrc->display, FALSE);
|
||||
#endif
|
||||
@ -1883,9 +2147,8 @@ clutter_cmp_process_event (MetaCompositor *compositor,
|
||||
screen = meta_window_get_screen (window);
|
||||
info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
if (mutter_plugin_manager_xevent_filter
|
||||
(info->plugin_mgr,
|
||||
event) == TRUE)
|
||||
if (mutter_plugin_manager_xevent_filter (info->plugin_mgr,
|
||||
event) == TRUE)
|
||||
return;
|
||||
}
|
||||
else
|
||||
@ -2006,44 +2269,20 @@ clutter_cmp_destroy_window (MetaCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
MutterWindow *cw = NULL;
|
||||
MetaScreen *screen = meta_window_get_screen (window);
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
MetaFrame *f = meta_window_get_frame (window);
|
||||
MutterWindowPrivate *priv;
|
||||
MutterWindow *cw = NULL;
|
||||
MetaScreen *screen = meta_window_get_screen (window);
|
||||
MetaFrame *f = meta_window_get_frame (window);
|
||||
Window xwindow;
|
||||
|
||||
/* Chances are we actually get the window frame here */
|
||||
cw = find_window_for_screen (screen,
|
||||
f ? meta_frame_get_xwindow (f) :
|
||||
meta_window_get_xwindow (window));
|
||||
xwindow = f ? meta_frame_get_xwindow (f) : meta_window_get_xwindow (window);
|
||||
|
||||
cw = find_window_for_screen (screen, xwindow);
|
||||
|
||||
if (!cw)
|
||||
return;
|
||||
|
||||
priv = cw->priv;
|
||||
|
||||
/*
|
||||
* We remove the window from internal lookup hashes and thus any other
|
||||
* unmap events etc fail
|
||||
*/
|
||||
info->windows = g_list_remove (info->windows, (gconstpointer) cw);
|
||||
g_hash_table_remove (info->windows_by_xid,
|
||||
(gpointer) (f ? meta_frame_get_xwindow (f) :
|
||||
meta_window_get_xwindow (window)));
|
||||
|
||||
/*
|
||||
* If a plugin manager is present, try to run an effect; if no effect of this
|
||||
* type is present, destroy the actor.
|
||||
*/
|
||||
priv->destroy_in_progress++;
|
||||
|
||||
if (!info->plugin_mgr ||
|
||||
!mutter_plugin_manager_event_simple (info->plugin_mgr,
|
||||
cw,
|
||||
MUTTER_PLUGIN_DESTROY))
|
||||
{
|
||||
priv->destroy_in_progress--;
|
||||
clutter_actor_destroy (CLUTTER_ACTOR (cw));
|
||||
}
|
||||
destroy_win (cw, FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2077,12 +2316,8 @@ clutter_cmp_minimize_window (MetaCompositor *compositor, MetaWindow *window)
|
||||
cw,
|
||||
MUTTER_PLUGIN_MINIMIZE))
|
||||
{
|
||||
ClutterActor *a = CLUTTER_ACTOR (cw);
|
||||
gint height = clutter_actor_get_height (a);
|
||||
|
||||
cw->priv->is_minimized = TRUE;
|
||||
cw->priv->minimize_in_progress--;
|
||||
clutter_actor_set_position (a, 0, -height);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -2181,65 +2416,109 @@ clutter_cmp_switch_workspace (MetaCompositor *compositor,
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
MetaCompScreen *info;
|
||||
GList *l;
|
||||
gint to_indx, from_indx;
|
||||
|
||||
info = meta_screen_get_compositor_data (screen);
|
||||
to_indx = meta_workspace_index (to);
|
||||
from_indx = meta_workspace_index (from);
|
||||
|
||||
printf ("Direction of switch %d\n", direction);
|
||||
|
||||
l = info->windows;
|
||||
while (l)
|
||||
if (!meta_prefs_get_live_hidden_windows ())
|
||||
{
|
||||
MutterWindow *cw = l->data;
|
||||
MetaWindow *mw = cw->priv->window;
|
||||
gboolean sticky;
|
||||
gint workspace = -1;
|
||||
/*
|
||||
* We are in the traditional mode where hidden windows get unmapped,
|
||||
* we need to pre-calculate the map status of each window so that once
|
||||
* the effect finishes we can put everything into proper order
|
||||
* (we need to ignore the map notifications during the effect so that
|
||||
* actors do not just disappear while the effect is running).
|
||||
*/
|
||||
GList *l = info->windows;
|
||||
|
||||
sticky = (!mw || meta_window_is_on_all_workspaces (mw));
|
||||
|
||||
if (!sticky)
|
||||
while (l)
|
||||
{
|
||||
MetaWorkspace *w;
|
||||
MutterWindow *cw = l->data;
|
||||
MetaWindow *mw = cw->priv->window;
|
||||
gboolean sticky;
|
||||
gint workspace = -1;
|
||||
|
||||
w = meta_window_get_workspace (cw->priv->window);
|
||||
workspace = meta_workspace_index (w);
|
||||
sticky = (!mw || meta_window_is_on_all_workspaces (mw));
|
||||
|
||||
/*
|
||||
* If the window is not on the target workspace, mark it for
|
||||
* unmap.
|
||||
*/
|
||||
if (to_indx != workspace)
|
||||
if (!sticky)
|
||||
{
|
||||
cw->priv->needs_unmap = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
cw->priv->needs_map = TRUE;
|
||||
cw->priv->needs_unmap = FALSE;
|
||||
MetaWorkspace *w;
|
||||
|
||||
w = meta_window_get_workspace (cw->priv->window);
|
||||
workspace = meta_workspace_index (w);
|
||||
|
||||
/*
|
||||
* If the window is not on the target workspace, mark it for
|
||||
* unmap.
|
||||
*/
|
||||
if (to_indx != workspace)
|
||||
{
|
||||
cw->priv->needs_unmap = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
cw->priv->needs_map = TRUE;
|
||||
cw->priv->needs_unmap = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
info->switch_workspace_in_progress++;
|
||||
|
||||
if (!info->plugin_mgr ||
|
||||
!mutter_plugin_manager_switch_workspace (
|
||||
info->plugin_mgr,
|
||||
(const GList **)&info->windows,
|
||||
from_indx,
|
||||
to_indx,
|
||||
direction))
|
||||
!mutter_plugin_manager_switch_workspace (info->plugin_mgr,
|
||||
(const GList **)&info->windows,
|
||||
from_indx,
|
||||
to_indx,
|
||||
direction))
|
||||
{
|
||||
info->switch_workspace_in_progress--;
|
||||
|
||||
/* We have to explicitely call this to fix up stacking order of the
|
||||
* actors; this is because the abs stacking position of actors does not
|
||||
* necessarily change during the window hiding/unhiding, only their
|
||||
* relative position toward the destkop window.
|
||||
*/
|
||||
mutter_finish_workspace_switch (info);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_cmp_ensure_stack_order (MetaCompositor *compositor,
|
||||
MetaScreen *screen)
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
GList *l = g_list_last (info->windows);
|
||||
|
||||
while (l)
|
||||
{
|
||||
ClutterActor *a = l->data;
|
||||
MutterWindow *mw = l->data;
|
||||
MetaWindow *window = mw->priv->window;
|
||||
|
||||
/*
|
||||
* If this window is not marked as hidden, we raise it.
|
||||
* If it has no MetaWindow associated (i.e., override redirect), we
|
||||
* raise it too. Everything else we push to the bottom.
|
||||
*/
|
||||
if (!window || !meta_window_is_hidden (window))
|
||||
{
|
||||
clutter_actor_raise_top (a);
|
||||
}
|
||||
else
|
||||
{
|
||||
clutter_actor_lower_bottom (a);
|
||||
}
|
||||
|
||||
l = l->prev;
|
||||
}
|
||||
}
|
||||
|
||||
static MetaCompositor comp_info = {
|
||||
clutter_cmp_destroy,
|
||||
@ -2256,7 +2535,8 @@ static MetaCompositor comp_info = {
|
||||
clutter_cmp_maximize_window,
|
||||
clutter_cmp_unmaximize_window,
|
||||
clutter_cmp_update_workspace_geometry,
|
||||
clutter_cmp_switch_workspace
|
||||
clutter_cmp_switch_workspace,
|
||||
clutter_cmp_ensure_stack_order,
|
||||
};
|
||||
|
||||
MetaCompositor *
|
||||
|
@ -884,3 +884,13 @@ mutter_plugin_set_stage_input_area (MutterPlugin *plugin,
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
|
||||
}
|
||||
|
||||
GList *
|
||||
mutter_plugin_get_windows (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *plugin_mgr = priv->self;
|
||||
|
||||
return mutter_get_windows (plugin_mgr->screen);
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,12 @@
|
||||
#include <gmodule.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../tidy/tidy-grid.h"
|
||||
|
||||
/* For debugging only */
|
||||
#include "../../../core/window-private.h"
|
||||
#include "compositor-mutter.h"
|
||||
|
||||
#define DESTROY_TIMEOUT 250
|
||||
#define MINIMIZE_TIMEOUT 250
|
||||
#define MAXIMIZE_TIMEOUT 250
|
||||
@ -43,6 +49,10 @@
|
||||
#define PANEL_SLIDE_THRESHOLD 2
|
||||
#define PANEL_HEIGHT 40
|
||||
#define ACTOR_DATA_KEY "MCCP-scratch-actor-data"
|
||||
|
||||
#define SWITCHER_CELL_WIDTH 200
|
||||
#define SWITCHER_CELL_HEIGHT 200
|
||||
|
||||
static GQuark actor_data_quark = 0;
|
||||
|
||||
typedef struct PluginPrivate PluginPrivate;
|
||||
@ -119,6 +129,8 @@ struct PluginPrivate
|
||||
ClutterActor *d_overlay ; /* arrow indicator */
|
||||
ClutterActor *panel;
|
||||
|
||||
ClutterActor *switcher;
|
||||
|
||||
gboolean debug_mode : 1;
|
||||
gboolean panel_out : 1;
|
||||
gboolean panel_out_in_progress : 1;
|
||||
@ -131,6 +143,8 @@ struct PluginPrivate
|
||||
struct ActorPrivate
|
||||
{
|
||||
ClutterActor *orig_parent;
|
||||
gint orig_x;
|
||||
gint orig_y;
|
||||
|
||||
ClutterTimeline *tml_minimize;
|
||||
ClutterTimeline *tml_maximize;
|
||||
@ -800,36 +814,225 @@ g_module_check_init (GModule *module)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void switcher_clone_weak_notify (gpointer data, GObject *object);
|
||||
|
||||
static void
|
||||
switcher_origin_weak_notify (gpointer data, GObject *object)
|
||||
{
|
||||
ClutterActor *clone = data;
|
||||
|
||||
/*
|
||||
* The original MutterWindow destroyed; remove the weak reference the
|
||||
* we added to the clone referencing the original window, then
|
||||
* destroy the clone.
|
||||
*/
|
||||
g_object_weak_unref (G_OBJECT (clone), switcher_clone_weak_notify, object);
|
||||
clutter_actor_destroy (clone);
|
||||
}
|
||||
|
||||
static void
|
||||
switcher_clone_weak_notify (gpointer data, GObject *object)
|
||||
{
|
||||
ClutterActor *origin = data;
|
||||
|
||||
/*
|
||||
* Clone destroyed -- this function gets only called whent the clone
|
||||
* is destroyed while the original MutterWindow still exists, so remove
|
||||
* the weak reference we added on the origin for sake of the clone.
|
||||
*/
|
||||
g_object_weak_unref (G_OBJECT (origin), switcher_origin_weak_notify, object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
switcher_clone_input_cb (ClutterActor *clone,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
MutterWindow *mw = data;
|
||||
MetaWindow *window;
|
||||
MetaWorkspace *workspace;
|
||||
|
||||
printf ("Actor %p (%s) clicked\n",
|
||||
clone, clutter_actor_get_name (clone));
|
||||
|
||||
window = mutter_window_get_meta_window (mw);
|
||||
workspace = meta_window_get_workspace (window);
|
||||
|
||||
meta_workspace_activate_with_focus (workspace, window, event->any.time);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a simple example of how a switcher might access the windows.
|
||||
*
|
||||
* Note that we use ClutterCloneTexture hooked up to the texture *inside*
|
||||
* MutterWindow (with FBO support, we could clone the entire MutterWindow,
|
||||
* although for the switcher purposes that is probably not what is wanted
|
||||
* anyway).
|
||||
*/
|
||||
static void
|
||||
hide_switcher (void)
|
||||
{
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
PluginPrivate *priv = plugin->plugin_private;
|
||||
|
||||
if (!priv->switcher)
|
||||
return;
|
||||
|
||||
clutter_actor_destroy (priv->switcher);
|
||||
priv->switcher = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
show_switcher (void)
|
||||
{
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
PluginPrivate *priv = plugin->plugin_private;
|
||||
ClutterActor *stage;
|
||||
GList *l;
|
||||
ClutterActor *switcher;
|
||||
TidyGrid *grid;
|
||||
guint panel_height;
|
||||
gint panel_y;
|
||||
|
||||
switcher = tidy_grid_new ();
|
||||
|
||||
grid = TIDY_GRID (switcher);
|
||||
|
||||
tidy_grid_set_homogenous_rows (grid, TRUE);
|
||||
tidy_grid_set_homogenous_columns (grid, TRUE);
|
||||
tidy_grid_set_column_major (grid, TRUE);
|
||||
tidy_grid_set_row_gap (grid, CLUTTER_UNITS_FROM_INT (10));
|
||||
tidy_grid_set_column_gap (grid, CLUTTER_UNITS_FROM_INT (10));
|
||||
|
||||
l = mutter_plugin_get_windows (plugin);
|
||||
while (l)
|
||||
{
|
||||
MutterWindow *mw = l->data;
|
||||
MetaCompWindowType type = mutter_window_get_window_type (mw);
|
||||
ClutterActor *a = CLUTTER_ACTOR (mw);
|
||||
ClutterActor *texture;
|
||||
ClutterActor *clone;
|
||||
guint w, h;
|
||||
gdouble s_x, s_y, s;
|
||||
|
||||
/*
|
||||
* Only show regular windows.
|
||||
*/
|
||||
if (mutter_window_is_override_redirect (mw) ||
|
||||
type != META_COMP_WINDOW_NORMAL)
|
||||
{
|
||||
l = l->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf ("Adding %p:%s\n",
|
||||
mw,
|
||||
mutter_window_get_meta_window (mw) ?
|
||||
mutter_window_get_meta_window (mw)->desc : "unknown");
|
||||
#endif
|
||||
|
||||
texture = mutter_window_get_texture (mw);
|
||||
clone = clutter_clone_texture_new (CLUTTER_TEXTURE (texture));
|
||||
|
||||
clutter_actor_set_name (clone, mutter_window_get_meta_window (mw)->desc);
|
||||
g_signal_connect (clone,
|
||||
"button-press-event",
|
||||
G_CALLBACK (switcher_clone_input_cb), mw);
|
||||
|
||||
g_object_weak_ref (G_OBJECT (mw), switcher_origin_weak_notify, clone);
|
||||
g_object_weak_ref (G_OBJECT (clone), switcher_clone_weak_notify, mw);
|
||||
|
||||
/*
|
||||
* Scale clone to fit the predefined size of the grid cell
|
||||
*/
|
||||
clutter_actor_get_size (a, &w, &h);
|
||||
s_x = (gdouble) SWITCHER_CELL_WIDTH / (gdouble) w;
|
||||
s_y = (gdouble) SWITCHER_CELL_HEIGHT / (gdouble) h;
|
||||
|
||||
s = s_x < s_y ? s_x : s_y;
|
||||
|
||||
if (s_x < s_y)
|
||||
clutter_actor_set_size (clone,
|
||||
(guint)((gdouble)w * s_x),
|
||||
(guint)((gdouble)h * s_x));
|
||||
else
|
||||
clutter_actor_set_size (clone,
|
||||
(guint)((gdouble)w * s_y),
|
||||
(guint)((gdouble)h * s_y));
|
||||
|
||||
clutter_actor_set_reactive (clone, TRUE);
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (grid), clone);
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
if (priv->switcher)
|
||||
hide_switcher ();
|
||||
|
||||
priv->switcher = switcher;
|
||||
|
||||
panel_height = clutter_actor_get_height (priv->panel);
|
||||
panel_y = clutter_actor_get_y (priv->panel);
|
||||
|
||||
clutter_actor_set_position (switcher, 10, panel_height + panel_y);
|
||||
|
||||
stage = mutter_plugin_get_stage (plugin);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), switcher);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_switcher ()
|
||||
{
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
PluginPrivate *priv = plugin->plugin_private;
|
||||
|
||||
if (priv->switcher)
|
||||
hide_switcher ();
|
||||
else
|
||||
show_switcher ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
stage_input_cb (ClutterActor *stage, ClutterEvent *event, gpointer data)
|
||||
{
|
||||
if (event->type == CLUTTER_MOTION)
|
||||
gboolean capture = GPOINTER_TO_INT (data);
|
||||
|
||||
if ((capture && event->type == CLUTTER_MOTION) ||
|
||||
(!capture && event->type == CLUTTER_BUTTON_PRESS))
|
||||
{
|
||||
ClutterMotionEvent *mev = (ClutterMotionEvent *) event;
|
||||
gint event_y;
|
||||
MutterPlugin *plugin = get_plugin ();
|
||||
PluginPrivate *priv = plugin->plugin_private;
|
||||
|
||||
if (event->type == CLUTTER_MOTION)
|
||||
event_y = ((ClutterMotionEvent*)event)->y;
|
||||
else
|
||||
event_y = ((ClutterButtonEvent*)event)->y;
|
||||
|
||||
if (priv->panel_out_in_progress || priv->panel_back_in_progress)
|
||||
return FALSE;
|
||||
|
||||
if (priv->panel_out)
|
||||
if (priv->panel_out &&
|
||||
(event->type == CLUTTER_BUTTON_PRESS || !priv->switcher))
|
||||
{
|
||||
guint height = clutter_actor_get_height (priv->panel);
|
||||
gint x = clutter_actor_get_x (priv->panel);
|
||||
|
||||
if (mev->y > (gint)height)
|
||||
if (event_y > (gint)height)
|
||||
{
|
||||
priv->panel_back_in_progress = TRUE;
|
||||
|
||||
clutter_effect_move (priv->panel_slide_effect,
|
||||
priv->panel, x, -height,
|
||||
on_panel_effect_complete,
|
||||
GINT_TO_POINTER (FALSE));
|
||||
priv->panel_out = FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
else if (mev->y < PANEL_SLIDE_THRESHOLD)
|
||||
else if (event_y < PANEL_SLIDE_THRESHOLD)
|
||||
{
|
||||
gint x = clutter_actor_get_x (priv->panel);
|
||||
|
||||
@ -840,11 +1043,20 @@ stage_input_cb (ClutterActor *stage, ClutterEvent *event, gpointer data)
|
||||
GINT_TO_POINTER (TRUE));
|
||||
|
||||
priv->panel_out = TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (event->type == CLUTTER_KEY_RELEASE)
|
||||
{
|
||||
ClutterKeyEvent *kev = (ClutterKeyEvent *) event;
|
||||
|
||||
return FALSE;
|
||||
g_print ("*** key press event (key:%c) ***\n",
|
||||
clutter_key_event_symbol (kev));
|
||||
|
||||
}
|
||||
|
||||
if (!capture && (event->type == CLUTTER_BUTTON_PRESS))
|
||||
{
|
||||
toggle_switcher ();
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@ -964,7 +1176,12 @@ do_init (const char *params)
|
||||
* children and do not interfere with their event processing.
|
||||
*/
|
||||
g_signal_connect (mutter_plugin_get_stage (plugin),
|
||||
"captured-event", G_CALLBACK (stage_input_cb), NULL);
|
||||
"captured-event", G_CALLBACK (stage_input_cb),
|
||||
GINT_TO_POINTER (TRUE));
|
||||
|
||||
g_signal_connect (mutter_plugin_get_stage (plugin),
|
||||
"button-press-event", G_CALLBACK (stage_input_cb),
|
||||
GINT_TO_POINTER (FALSE));
|
||||
|
||||
mutter_plugin_set_stage_input_area (plugin, 0, 0, screen_width, 1);
|
||||
|
||||
|
1000
src/compositor/mutter/tidy/tidy-grid.c
Normal file
1000
src/compositor/mutter/tidy/tidy-grid.c
Normal file
File diff suppressed because it is too large
Load Diff
99
src/compositor/mutter/tidy/tidy-grid.h
Normal file
99
src/compositor/mutter/tidy/tidy-grid.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2008 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __TIDY_GRID_H__
|
||||
#define __TIDY_GRID_H__
|
||||
|
||||
#include <clutter/clutter-actor.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define TIDY_TYPE_GRID (tidy_grid_get_type())
|
||||
#define TIDY_GRID(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
TIDY_TYPE_GRID, \
|
||||
TidyGrid))
|
||||
#define TIDY_GRID_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
TIDY_TYPE_GRID, \
|
||||
TidyGridClass))
|
||||
#define TIDY_IS_GRID(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
TIDY_TYPE_GRID))
|
||||
#define TIDY_IS_GRID_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
TIDY_TYPE_GRID))
|
||||
#define TIDY_GRID_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
TIDY_TYPE_GRID, \
|
||||
TidyGridClass))
|
||||
|
||||
typedef struct _TidyGrid TidyGrid;
|
||||
typedef struct _TidyGridClass TidyGridClass;
|
||||
typedef struct _TidyGridPrivate TidyGridPrivate;
|
||||
|
||||
struct _TidyGridClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
};
|
||||
|
||||
struct _TidyGrid
|
||||
{
|
||||
ClutterActor parent;
|
||||
|
||||
TidyGridPrivate *priv;
|
||||
};
|
||||
|
||||
GType tidy_grid_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterActor *tidy_grid_new (void);
|
||||
void tidy_grid_set_end_align (TidyGrid *self,
|
||||
gboolean value);
|
||||
gboolean tidy_grid_get_end_align (TidyGrid *self);
|
||||
void tidy_grid_set_homogenous_rows (TidyGrid *self,
|
||||
gboolean value);
|
||||
gboolean tidy_grid_get_homogenous_rows (TidyGrid *self);
|
||||
void tidy_grid_set_homogenous_columns (TidyGrid *self,
|
||||
gboolean value);
|
||||
gboolean tidy_grid_get_homogenous_columns (TidyGrid *self);
|
||||
void tidy_grid_set_column_major (TidyGrid *self,
|
||||
gboolean value);
|
||||
gboolean tidy_grid_get_column_major (TidyGrid *self);
|
||||
void tidy_grid_set_row_gap (TidyGrid *self,
|
||||
ClutterUnit value);
|
||||
ClutterUnit tidy_grid_get_row_gap (TidyGrid *self);
|
||||
void tidy_grid_set_column_gap (TidyGrid *self,
|
||||
ClutterUnit value);
|
||||
ClutterUnit tidy_grid_get_column_gap (TidyGrid *self);
|
||||
void tidy_grid_set_valign (TidyGrid *self,
|
||||
gdouble value);
|
||||
gdouble tidy_grid_get_valign (TidyGrid *self);
|
||||
void tidy_grid_set_halign (TidyGrid *self,
|
||||
gdouble value);
|
||||
gdouble tidy_grid_get_halign (TidyGrid *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __TIDY_GRID_H__ */
|
@ -68,6 +68,8 @@
|
||||
#define KEY_CLUTTER_PLUGINS "/apps/metacity/general/clutter_plugins"
|
||||
#endif
|
||||
|
||||
#define KEY_LIVE_HIDDEN_WINDOWS "/apps/metacity/general/live_hidden_windows"
|
||||
|
||||
#ifdef HAVE_GCONF
|
||||
static GConfClient *default_client = NULL;
|
||||
static GList *changes = NULL;
|
||||
@ -114,6 +116,8 @@ static gboolean clutter_disabled = FALSE;
|
||||
static GSList *clutter_plugins = NULL;
|
||||
#endif
|
||||
|
||||
static gboolean live_hidden_windows = FALSE;
|
||||
|
||||
#ifdef HAVE_GCONF
|
||||
static gboolean handle_preference_update_enum (const gchar *key, GConfValue *value);
|
||||
|
||||
@ -423,6 +427,11 @@ static MetaBoolPreference preferences_bool[] =
|
||||
FALSE,
|
||||
},
|
||||
#endif
|
||||
{ "/apps/metacity/general/live_hidden_windows",
|
||||
META_PREF_LIVE_HIDDEN_WINDOWS,
|
||||
&live_hidden_windows,
|
||||
FALSE,
|
||||
},
|
||||
{ NULL, 0, NULL, FALSE },
|
||||
};
|
||||
|
||||
@ -1827,6 +1836,8 @@ meta_preference_to_string (MetaPreference pref)
|
||||
case META_PREF_CLUTTER_PLUGINS:
|
||||
return "CLUTTER_PLUGINS";
|
||||
#endif
|
||||
case META_PREF_LIVE_HIDDEN_WINDOWS:
|
||||
return "LIVE_HIDDEN_WINDOWS";
|
||||
}
|
||||
|
||||
return "(unknown)";
|
||||
@ -2962,6 +2973,34 @@ meta_prefs_set_clutter_plugins (GSList *list)
|
||||
}
|
||||
#endif
|
||||
|
||||
gboolean
|
||||
meta_prefs_get_live_hidden_windows (void)
|
||||
{
|
||||
return live_hidden_windows;
|
||||
}
|
||||
|
||||
void
|
||||
meta_prefs_set_live_hidden_windows (gboolean whether)
|
||||
{
|
||||
#ifdef HAVE_GCONF
|
||||
GError *err = NULL;
|
||||
|
||||
gconf_client_set_bool (default_client,
|
||||
KEY_LIVE_HIDDEN_WINDOWS,
|
||||
whether,
|
||||
&err);
|
||||
|
||||
if (err)
|
||||
{
|
||||
meta_warning (_("Error setting live hidden windows status status: %s\n"),
|
||||
err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
#else
|
||||
live_hidden_windows = whether;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAVE_GCONF
|
||||
static void
|
||||
init_button_layout(void)
|
||||
|
@ -772,6 +772,17 @@ meta_screen_manage_all_windows (MetaScreen *screen)
|
||||
}
|
||||
meta_stack_thaw (screen->stack);
|
||||
|
||||
/*
|
||||
* Because the windows have already been created/mapped/etc, if the compositor
|
||||
* maintains a separate stack based on ConfigureNotify restack messages, it
|
||||
* will not necessarily get what it needs; we explicitely notify the
|
||||
* compositor to fix up its stacking order.
|
||||
*
|
||||
* For more on this issue, see comments in meta_window_hide().
|
||||
*/
|
||||
if (screen->display->compositor)
|
||||
meta_compositor_ensure_stack_order (screen->display->compositor, screen);
|
||||
|
||||
g_list_foreach (windows, (GFunc)g_free, NULL);
|
||||
g_list_free (windows);
|
||||
|
||||
|
@ -241,6 +241,12 @@ get_standalone_layer (MetaWindow *window)
|
||||
MetaStackLayer layer;
|
||||
gboolean focused_transient = FALSE;
|
||||
|
||||
if (window->hidden)
|
||||
{
|
||||
layer = META_LAYER_DESKTOP;
|
||||
return layer;
|
||||
}
|
||||
|
||||
switch (window->type)
|
||||
{
|
||||
case META_WINDOW_DESKTOP:
|
||||
@ -329,7 +335,8 @@ compute_layer (MetaWindow *window)
|
||||
* windows getting in fullscreen layer if any terminal is
|
||||
* fullscreen.
|
||||
*/
|
||||
if (WINDOW_HAS_TRANSIENT_TYPE(window) &&
|
||||
if (window->layer != META_LAYER_DESKTOP &&
|
||||
WINDOW_HAS_TRANSIENT_TYPE(window) &&
|
||||
(window->xtransient_for == None ||
|
||||
window->transient_parent_is_root_window))
|
||||
{
|
||||
@ -854,7 +861,6 @@ stack_do_relayer (MetaStack *stack)
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"Window %s moved from layer %u to %u\n",
|
||||
w->desc, old_layer, w->layer);
|
||||
|
||||
stack->need_resort = TRUE;
|
||||
stack->need_constrain = TRUE;
|
||||
/* don't need to constrain as constraining
|
||||
|
@ -150,6 +150,11 @@ struct _MetaWindow
|
||||
*/
|
||||
guint mapped : 1;
|
||||
|
||||
/* Whether window has been hidden from view by lowering it to the bottom
|
||||
* of window stack.
|
||||
*/
|
||||
guint hidden : 1;
|
||||
|
||||
/* Iconic is the state in WM_STATE; happens for workspaces/shading
|
||||
* in addition to minimize
|
||||
*/
|
||||
@ -393,11 +398,6 @@ void meta_window_change_workspace (MetaWindow *window,
|
||||
void meta_window_stick (MetaWindow *window);
|
||||
void meta_window_unstick (MetaWindow *window);
|
||||
|
||||
void meta_window_activate (MetaWindow *window,
|
||||
guint32 current_time);
|
||||
void meta_window_activate_with_workspace (MetaWindow *window,
|
||||
guint32 current_time,
|
||||
MetaWorkspace *workspace);
|
||||
void meta_window_make_fullscreen_internal (MetaWindow *window);
|
||||
void meta_window_make_fullscreen (MetaWindow *window);
|
||||
void meta_window_unmake_fullscreen (MetaWindow *window);
|
||||
|
@ -472,6 +472,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
||||
window->tab_unminimized = FALSE;
|
||||
window->iconic = FALSE;
|
||||
window->mapped = attrs->map_state != IsUnmapped;
|
||||
window->hidden = 0;
|
||||
/* if already mapped, no need to worry about focus-on-first-time-showing */
|
||||
window->showing_for_first_time = !window->mapped;
|
||||
/* if already mapped we don't want to do the placement thing */
|
||||
@ -2243,8 +2244,22 @@ meta_window_show (MetaWindow *window)
|
||||
XMapWindow (window->display->xdisplay, window->xwindow);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
did_show = TRUE;
|
||||
window->hidden = FALSE;
|
||||
}
|
||||
else if (meta_prefs_get_live_hidden_windows ())
|
||||
{
|
||||
if (window->hidden && window->type != META_WINDOW_DESKTOP)
|
||||
{
|
||||
window->hidden = FALSE;
|
||||
meta_stack_freeze (window->screen->stack);
|
||||
meta_window_update_layer (window);
|
||||
meta_window_raise (window);
|
||||
meta_stack_thaw (window->screen->stack);
|
||||
did_show = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (window->was_minimized)
|
||||
if (did_show && window->was_minimized)
|
||||
{
|
||||
MetaRectangle window_rect;
|
||||
MetaRectangle icon_rect;
|
||||
@ -2261,7 +2276,6 @@ meta_window_show (MetaWindow *window)
|
||||
NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (window->iconic)
|
||||
{
|
||||
@ -2315,27 +2329,77 @@ meta_window_hide (MetaWindow *window)
|
||||
|
||||
did_hide = FALSE;
|
||||
|
||||
if (window->frame && window->frame->mapped)
|
||||
if (meta_prefs_get_live_hidden_windows ())
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_STATE, "Frame actually needs unmap\n");
|
||||
window->frame->mapped = FALSE;
|
||||
meta_ui_unmap_frame (window->screen->ui, window->frame->xwindow);
|
||||
did_hide = TRUE;
|
||||
}
|
||||
gboolean was_mapped;
|
||||
|
||||
if (window->mapped)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"%s actually needs unmap\n", window->desc);
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"Incrementing unmaps_pending on %s for hide\n",
|
||||
window->desc);
|
||||
window->mapped = FALSE;
|
||||
window->unmaps_pending += 1;
|
||||
meta_error_trap_push (window->display);
|
||||
XUnmapWindow (window->display->xdisplay, window->xwindow);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
if (window->hidden)
|
||||
return;
|
||||
|
||||
was_mapped = window->mapped;
|
||||
|
||||
if (!was_mapped)
|
||||
meta_window_show (window);
|
||||
|
||||
window->hidden = TRUE;
|
||||
did_hide = TRUE;
|
||||
|
||||
meta_stack_freeze (window->screen->stack);
|
||||
meta_window_update_layer (window);
|
||||
meta_window_lower (window);
|
||||
meta_stack_thaw (window->screen->stack);
|
||||
|
||||
/*
|
||||
* The X server does not implement lower-below semantics for restacking
|
||||
* windows, only raise-above; consequently each single lower-bottom call
|
||||
* gets translated to a bunch of raise-above moves, and often there will
|
||||
* be no ConfigureNotify at all for the window we are lowering (only for
|
||||
* its siblings). If we mix the lower-bottom sequence of calls with
|
||||
* mapping of windows, the batch of ConfigureNotify events that is
|
||||
* generated does not correctly reflect the stack order, and if the
|
||||
* Compositor relies on these for its own internal stack, it will
|
||||
* invariably end up with wrong stacking order.
|
||||
*
|
||||
* I have not been able to find a way to get this just work so that the
|
||||
* resulting ConfigureNotify messages would reflect the actual state of
|
||||
* the stack, so in the special case we map a window while hiding it, we
|
||||
* explitely notify the compositor that it should ensure its stacking
|
||||
* matches the cannonical stack of the WM.
|
||||
*
|
||||
* NB: this is uncommon, and generally only happens on the WM start up,
|
||||
* when we are taking over pre-existing windows, so this brute-force
|
||||
* fix is OK performance wise.
|
||||
*/
|
||||
if (!was_mapped && window->display->compositor)
|
||||
{
|
||||
meta_compositor_ensure_stack_order (window->display->compositor,
|
||||
window->screen);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (window->frame && window->frame->mapped)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_STATE, "Frame actually needs unmap\n");
|
||||
window->frame->mapped = FALSE;
|
||||
meta_ui_unmap_frame (window->screen->ui, window->frame->xwindow);
|
||||
did_hide = TRUE;
|
||||
}
|
||||
|
||||
if (window->mapped)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"%s actually needs unmap\n", window->desc);
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"Incrementing unmaps_pending on %s for hide\n",
|
||||
window->desc);
|
||||
window->mapped = FALSE;
|
||||
window->unmaps_pending += 1;
|
||||
meta_error_trap_push (window->display);
|
||||
XUnmapWindow (window->display->xdisplay, window->xwindow);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
did_hide = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!window->iconic)
|
||||
@ -7974,7 +8038,7 @@ meta_window_update_layer (MetaWindow *window)
|
||||
|
||||
meta_stack_freeze (window->screen->stack);
|
||||
group = meta_window_get_group (window);
|
||||
if (group)
|
||||
if (!window->hidden && group)
|
||||
meta_group_update_layers (group);
|
||||
else
|
||||
meta_stack_update_layer (window->screen->stack, window);
|
||||
@ -8223,3 +8287,9 @@ meta_window_is_on_all_workspaces (MetaWindow *window)
|
||||
return window->on_all_workspaces;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_window_is_hidden (MetaWindow *window)
|
||||
{
|
||||
return window->hidden;
|
||||
}
|
||||
|
||||
|
@ -65,11 +65,6 @@ void meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||
MetaWindow *window);
|
||||
void meta_workspace_relocate_windows (MetaWorkspace *workspace,
|
||||
MetaWorkspace *new_home);
|
||||
void meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||
MetaWindow *focus_this,
|
||||
guint32 timestamp);
|
||||
void meta_workspace_activate (MetaWorkspace *workspace,
|
||||
guint32 timestamp);
|
||||
GList* meta_workspace_list_windows (MetaWorkspace *workspace);
|
||||
|
||||
void meta_workspace_invalidate_work_area (MetaWorkspace *workspace);
|
||||
|
@ -306,7 +306,19 @@ meta_workspace_queue_calc_showing (MetaWorkspace *workspace)
|
||||
tmp = workspace->windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
meta_window_queue (tmp->data, META_QUEUE_CALC_SHOWING);
|
||||
if (meta_prefs_get_live_hidden_windows ())
|
||||
{
|
||||
/*
|
||||
* When we hide rather than unmap windows, we need the show/hide
|
||||
* status of the window to be recalculated *before* we call the
|
||||
* compositor switch_workspace hook.
|
||||
*/
|
||||
meta_window_calc_showing (tmp->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_window_queue (tmp->data, META_QUEUE_CALC_SHOWING);
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
@ -57,10 +57,13 @@ struct _MutterWindow
|
||||
|
||||
GType mutter_window_get_type (void);
|
||||
|
||||
Window mutter_window_get_x_window (MutterWindow *mcw);
|
||||
MetaCompWindowType mutter_window_get_window_type (MutterWindow *mcw);
|
||||
gint mutter_window_get_workspace (MutterWindow *mcw);
|
||||
|
||||
Window mutter_window_get_x_window (MutterWindow *mcw);
|
||||
MetaCompWindowType mutter_window_get_window_type (MutterWindow *mcw);
|
||||
gint mutter_window_get_workspace (MutterWindow *mcw);
|
||||
gboolean mutter_window_is_hidden (MutterWindow *mcw);
|
||||
MetaWindow * mutter_window_get_meta_window (MutterWindow *mcw);
|
||||
ClutterActor * mutter_window_get_texture (MutterWindow *mcw);
|
||||
gboolean mutter_window_is_override_redirect (MutterWindow *mcw);
|
||||
|
||||
/* Compositor API */
|
||||
MetaCompositor *mutter_new (MetaDisplay *display);
|
||||
@ -70,5 +73,6 @@ void mutter_window_effect_completed (MutterWindow *actor, gulong event);
|
||||
ClutterActor * mutter_get_stage_for_screen (MetaScreen *screen);
|
||||
ClutterActor * mutter_get_overlay_group_for_screen (MetaScreen *screen);
|
||||
Window mutter_get_overlay_window (MetaScreen *screen);
|
||||
GList * mutter_get_windows (MetaScreen *screen);
|
||||
|
||||
#endif
|
||||
|
@ -127,6 +127,11 @@ meta_compositor_switch_workspace (MetaCompositor *compositor,
|
||||
MetaWorkspace *from,
|
||||
MetaWorkspace *to,
|
||||
MetaMotionDirection direction);
|
||||
|
||||
void
|
||||
meta_compositor_ensure_stack_order (MetaCompositor *compositor,
|
||||
MetaScreen *screen);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -225,4 +225,7 @@ void
|
||||
mutter_plugin_set_stage_input_area (MutterPlugin *plugin,
|
||||
gint x, gint y, gint width, gint height);
|
||||
|
||||
GList *
|
||||
mutter_plugin_get_windows (MutterPlugin *plugin);
|
||||
|
||||
#endif /* MUTTER_PLUGIN_H_ */
|
||||
|
@ -62,8 +62,9 @@ typedef enum
|
||||
META_PREF_COMPOSITING_MANAGER,
|
||||
#ifdef WITH_CLUTTER
|
||||
META_PREF_CLUTTER_DISABLED,
|
||||
META_PREF_CLUTTER_PLUGINS
|
||||
META_PREF_CLUTTER_PLUGINS,
|
||||
#endif
|
||||
META_PREF_LIVE_HIDDEN_WINDOWS,
|
||||
} MetaPreference;
|
||||
|
||||
typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
|
||||
@ -139,6 +140,10 @@ GSList * meta_prefs_get_clutter_plugins (void);
|
||||
void meta_prefs_set_clutter_plugins (GSList *list);
|
||||
#endif
|
||||
|
||||
gboolean meta_prefs_get_live_hidden_windows (void);
|
||||
void meta_prefs_set_live_hidden_windows (gboolean whether);
|
||||
|
||||
|
||||
/* XXX FIXME This should be x-macroed, but isn't yet because it would be
|
||||
* difficult (or perhaps impossible) to add the suffixes using the current
|
||||
* system. It needs some more thought, perhaps after the current system
|
||||
|
@ -58,4 +58,10 @@ MetaWindowType meta_window_get_type (MetaWindow *window);
|
||||
Atom meta_window_get_type_atom (MetaWindow *window);
|
||||
MetaWorkspace *meta_window_get_workspace (MetaWindow *window);
|
||||
gboolean meta_window_is_on_all_workspaces (MetaWindow *window);
|
||||
gboolean meta_window_is_hidden (MetaWindow *window);
|
||||
void meta_window_activate (MetaWindow *window,guint32 current_time);
|
||||
void meta_window_activate_with_workspace (MetaWindow *window,
|
||||
guint32 current_time,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
#endif
|
||||
|
@ -57,4 +57,8 @@ int meta_workspace_index (MetaWorkspace *workspace);
|
||||
MetaScreen *meta_workspace_get_screen (MetaWorkspace *workspace);
|
||||
void meta_workspace_get_work_area_all_xineramas (MetaWorkspace *workspace,
|
||||
MetaRectangle *area);
|
||||
void meta_workspace_activate (MetaWorkspace *workspace, guint32 timestamp);
|
||||
void meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||
MetaWindow *focus_this,
|
||||
guint32 timestamp);
|
||||
#endif
|
||||
|
@ -370,6 +370,22 @@
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/metacity/general/live_hidden_windows</key>
|
||||
<applyto>/apps/metacity/general/live_hidden_windows</applyto>
|
||||
<owner>metacity</owner>
|
||||
<type>bool</type>
|
||||
<default>false</default>
|
||||
<locale name="C">
|
||||
<short>Live Hidden Windows</short>
|
||||
<long>
|
||||
Determines whether hidden windows (i.e., minimized windows and
|
||||
windows on other workspaces than the current one) should be kept
|
||||
alive.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/metacity/workspace_names/name</key>
|
||||
<applyto>/apps/metacity/workspace_names/name_1</applyto>
|
||||
|
Loading…
Reference in New Issue
Block a user