sliding panel

This commit is contained in:
Tomas Frydrych 2008-10-16 15:50:03 +01:00
parent d185a84140
commit b5414c27a3
3 changed files with 109 additions and 70 deletions

View File

@ -30,6 +30,7 @@
#define N_(x) x #define N_(x) x
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <clutter/x11/clutter-x11.h>
#include <gmodule.h> #include <gmodule.h>
#include <string.h> #include <string.h>
@ -40,7 +41,7 @@
#define SWITCH_TIMEOUT 500 #define SWITCH_TIMEOUT 500
#define PANEL_SLIDE_TIMEOUT 250; \ #define PANEL_SLIDE_TIMEOUT 250; \
#define PANEL_SLIDE_THRESHOLD 3 #define PANEL_SLIDE_THRESHOLD 2
#define PANEL_HEIGHT 40 #define PANEL_HEIGHT 40
#define ACTOR_DATA_KEY "MCCP-Moblin-actor-data" #define ACTOR_DATA_KEY "MCCP-Moblin-actor-data"
@ -98,6 +99,7 @@ MetaCompositorClutterPlugin META_COMPOSITOR_CLUTTER_PLUGIN_STRUCT =
.unmaximize = unmaximize, .unmaximize = unmaximize,
.switch_workspace = switch_workspace, .switch_workspace = switch_workspace,
.kill_effect = kill_effect, .kill_effect = kill_effect,
.xevent_filter = xevent_filter,
/* The reload handler */ /* The reload handler */
.reload = reload .reload = reload
@ -126,6 +128,8 @@ struct PluginPrivate
gboolean debug_mode : 1; gboolean debug_mode : 1;
gboolean panel_out : 1; gboolean panel_out : 1;
gboolean panel_out_in_progress : 1;
gboolean panel_back_in_progress : 1;
}; };
/* /*
@ -612,58 +616,30 @@ on_panel_effect_complete (ClutterActor *panel, gpointer data)
{ {
gboolean reactive = GPOINTER_TO_INT (data); gboolean reactive = GPOINTER_TO_INT (data);
MetaCompositorClutterPlugin *plugin = get_plugin (); MetaCompositorClutterPlugin *plugin = get_plugin ();
PluginPrivate *priv = plugin->plugin_private;
if (reactive) if (reactive)
meta_comp_clutter_plugin_set_stage_reactive (plugin, reactive); {
priv->panel_out_in_progress = FALSE;
meta_comp_clutter_plugin_set_stage_reactive (plugin, reactive);
}
else else
meta_comp_clutter_plugin_set_stage_input_area (plugin, 0, 0, {
priv->panel_back_in_progress = FALSE;
meta_comp_clutter_plugin_set_stage_input_area (plugin, 0, 0,
plugin->screen_width, 1); plugin->screen_width, 1);
}
} }
static gboolean static gboolean
xevent_filter (XEvent *xev) xevent_filter (XEvent *xev)
{ {
MetaCompositorClutterPlugin *plugin = get_plugin (); MetaCompositorClutterPlugin *plugin = get_plugin ();
PluginPrivate *priv = plugin->plugin_private; ClutterActor *stage;
if (xev->type != MotionNotify) stage = meta_comp_clutter_plugin_get_stage (plugin);
return FALSE;
printf ("got xevent type %d on 0x%x @ y %d\n", clutter_x11_handle_event (xev);
xev->type,
(gint) xev->xmotion.window,
xev->xmotion.y_root);
if (priv->panel_out)
{
guint height = clutter_actor_get_height (priv->panel);
gint x = clutter_actor_get_x (priv->panel);
if (xev->xmotion.y_root > (gint)height)
{
clutter_effect_move (priv->panel_slide_effect,
priv->panel, x, -height,
on_panel_effect_complete,
GINT_TO_POINTER (FALSE));
}
priv->panel_out = FALSE;
return TRUE;
}
else if (xev->xmotion.y_root < PANEL_SLIDE_THRESHOLD)
{
gint x = clutter_actor_get_x (priv->panel);
clutter_effect_move (priv->panel_slide_effect,
priv->panel, x, 0,
on_panel_effect_complete,
GINT_TO_POINTER (TRUE ));
priv->panel_out = TRUE;
return TRUE;
}
return FALSE; return FALSE;
} }
@ -746,15 +722,14 @@ g_module_check_init (GModule *module)
static gboolean static gboolean
stage_input_cb (ClutterActor *stage, ClutterEvent *event, gpointer data) stage_input_cb (ClutterActor *stage, ClutterEvent *event, gpointer data)
{ {
printf ("Got event, type %d\n", event->type);
if (event->type == CLUTTER_MOTION) if (event->type == CLUTTER_MOTION)
{ {
ClutterMotionEvent *mev = (ClutterMotionEvent *) event; ClutterMotionEvent *mev = (ClutterMotionEvent *) event;
MetaCompositorClutterPlugin *plugin = get_plugin (); MetaCompositorClutterPlugin *plugin = get_plugin ();
PluginPrivate *priv = plugin->plugin_private; PluginPrivate *priv = plugin->plugin_private;
printf ("got stage motion event at y %d\n", mev->y); if (priv->panel_out_in_progress || priv->panel_back_in_progress)
return FALSE;
if (priv->panel_out) if (priv->panel_out)
{ {
@ -763,24 +738,25 @@ stage_input_cb (ClutterActor *stage, ClutterEvent *event, gpointer data)
if (mev->y > (gint)height) if (mev->y > (gint)height)
{ {
priv->panel_back_in_progress = TRUE;
clutter_effect_move (priv->panel_slide_effect, clutter_effect_move (priv->panel_slide_effect,
priv->panel, x, -height, priv->panel, x, -height,
on_panel_effect_complete, on_panel_effect_complete,
GINT_TO_POINTER (FALSE)); GINT_TO_POINTER (FALSE));
priv->panel_out = FALSE;
} }
priv->panel_out = FALSE;
return TRUE; return TRUE;
} }
else if (mev->y < PANEL_SLIDE_THRESHOLD) else if (mev->y < PANEL_SLIDE_THRESHOLD)
{ {
gint x = clutter_actor_get_x (priv->panel); gint x = clutter_actor_get_x (priv->panel);
priv->panel_out_in_progress = TRUE;
clutter_effect_move (priv->panel_slide_effect, clutter_effect_move (priv->panel_slide_effect,
priv->panel, x, 0, priv->panel, x, 0,
on_panel_effect_complete, on_panel_effect_complete,
GINT_TO_POINTER (TRUE )); GINT_TO_POINTER (TRUE));
priv->panel_out = TRUE; priv->panel_out = TRUE;
@ -793,6 +769,23 @@ stage_input_cb (ClutterActor *stage, ClutterEvent *event, gpointer data)
return FALSE; return FALSE;
} }
static ClutterActor *
make_panel (gint width)
{
ClutterActor *panel;
ClutterActor *background;
ClutterColor clr = {0xff, 0, 0, 0xff};
panel = clutter_group_new ();
/* FIME -- size and color */
background = clutter_rectangle_new_with_color (&clr);
clutter_container_add_actor (CLUTTER_CONTAINER (panel), background);
clutter_actor_set_size (background, width, PANEL_HEIGHT);
return panel;
}
/* /*
* Core of the plugin init function, called for initial initialization and * Core of the plugin init function, called for initial initialization and
* by the reload() function. Returns TRUE on success. * by the reload() function. Returns TRUE on success.
@ -811,8 +804,8 @@ do_init ()
guint switch_timeout = SWITCH_TIMEOUT; guint switch_timeout = SWITCH_TIMEOUT;
guint panel_slide_timeout = PANEL_SLIDE_TIMEOUT; guint panel_slide_timeout = PANEL_SLIDE_TIMEOUT;
const gchar *name; const gchar *name;
ClutterActor *overlay, *background; ClutterActor *overlay;
ClutterColor clr = {0xff, 0, 0, 0xff}; ClutterActor *panel;
plugin->plugin_private = priv; plugin->plugin_private = priv;
@ -901,30 +894,22 @@ do_init ()
overlay = meta_comp_clutter_plugin_get_overlay_group (plugin); overlay = meta_comp_clutter_plugin_get_overlay_group (plugin);
priv->panel = clutter_group_new (); panel = priv->panel = make_panel (plugin->screen_width);
clutter_container_add_actor (CLUTTER_CONTAINER (overlay), priv->panel); clutter_container_add_actor (CLUTTER_CONTAINER (overlay), panel);
priv->panel_slide_effect priv->panel_slide_effect
= clutter_effect_template_new (clutter_timeline_new_for_duration ( = clutter_effect_template_new (clutter_timeline_new_for_duration (
panel_slide_timeout), panel_slide_timeout),
CLUTTER_ALPHA_SINE_INC); CLUTTER_ALPHA_SINE_INC);
/* FIME -- size and color */ clutter_actor_set_position (panel, 0,
background = clutter_rectangle_new_with_color (&clr); -clutter_actor_get_height (panel));
clutter_container_add_actor (CLUTTER_CONTAINER (priv->panel), background);
clutter_actor_set_size (background, plugin->screen_width, PANEL_HEIGHT);
clutter_actor_set_position (background, 0,
-clutter_actor_get_height (background));
g_signal_connect (meta_comp_clutter_plugin_get_stage (plugin), g_signal_connect (meta_comp_clutter_plugin_get_stage (plugin),
"motion-event", G_CALLBACK (stage_input_cb), NULL); "motion-event", G_CALLBACK (stage_input_cb), NULL);
g_signal_connect (meta_comp_clutter_plugin_get_stage (plugin),
"button-press-event", G_CALLBACK (stage_input_cb), NULL);
meta_comp_clutter_plugin_set_stage_input_area (plugin, 0, 0, meta_comp_clutter_plugin_set_stage_input_area (plugin, 0, 0,
plugin->screen_width, 60); plugin->screen_width, 1);
clutter_set_motion_events_enabled (TRUE); clutter_set_motion_events_enabled (TRUE);

View File

@ -32,6 +32,7 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/extensions/Xfixes.h> #include <X11/extensions/Xfixes.h>
#include <X11/extensions/shape.h> #include <X11/extensions/shape.h>
#include <clutter/x11/clutter-x11.h>
static gboolean meta_compositor_clutter_plugin_manager_reload (MetaCompositorClutterPluginManager *mgr); static gboolean meta_compositor_clutter_plugin_manager_reload (MetaCompositorClutterPluginManager *mgr);
@ -722,9 +723,12 @@ meta_comp_clutter_plugin_set_stage_reactive (MetaCompositorClutterPlugin *plugin
MetaCompositorClutterPluginManager *mgr = priv->self; MetaCompositorClutterPluginManager *mgr = priv->self;
MetaDisplay *display = meta_screen_get_display (mgr->screen); MetaDisplay *display = meta_screen_get_display (mgr->screen);
Display *xdpy = meta_display_get_xdisplay (display); Display *xdpy = meta_display_get_xdisplay (display);
Window overlay; Window xstage, xoverlay;
ClutterActor *stage;
overlay = meta_compositor_clutter_get_overlay_window (mgr->screen); stage = meta_compositor_clutter_get_stage_for_screen (mgr->screen);
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
xoverlay = meta_compositor_clutter_get_overlay_window (mgr->screen);
static XserverRegion region = None; static XserverRegion region = None;
@ -733,12 +737,16 @@ meta_comp_clutter_plugin_set_stage_reactive (MetaCompositorClutterPlugin *plugin
if (reactive) if (reactive)
{ {
XFixesSetWindowShapeRegion (xdpy, overlay, XFixesSetWindowShapeRegion (xdpy, xstage,
ShapeInput, 0, 0, None);
XFixesSetWindowShapeRegion (xdpy, xoverlay,
ShapeInput, 0, 0, None); ShapeInput, 0, 0, None);
} }
else else
{ {
XFixesSetWindowShapeRegion (xdpy, overlay, XFixesSetWindowShapeRegion (xdpy, xstage,
ShapeInput, 0, 0, region);
XFixesSetWindowShapeRegion (xdpy, xoverlay,
ShapeInput, 0, 0, region); ShapeInput, 0, 0, region);
} }
} }
@ -751,11 +759,14 @@ meta_comp_clutter_plugin_set_stage_input_area (MetaCompositorClutterPlugin *plug
MetaCompositorClutterPluginManager *mgr = priv->self; MetaCompositorClutterPluginManager *mgr = priv->self;
MetaDisplay *display = meta_screen_get_display (mgr->screen); MetaDisplay *display = meta_screen_get_display (mgr->screen);
Display *xdpy = meta_display_get_xdisplay (display); Display *xdpy = meta_display_get_xdisplay (display);
Window overlay; Window xstage, xoverlay;
ClutterActor *stage;
XRectangle rect; XRectangle rect;
XserverRegion region; XserverRegion region;
overlay = meta_compositor_clutter_get_overlay_window (mgr->screen); stage = meta_compositor_clutter_get_stage_for_screen (mgr->screen);
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
xoverlay = meta_compositor_clutter_get_overlay_window (mgr->screen);
rect.x = x; rect.x = x;
rect.y = y; rect.y = y;
@ -764,5 +775,6 @@ meta_comp_clutter_plugin_set_stage_input_area (MetaCompositorClutterPlugin *plug
region = XFixesCreateRegion (xdpy, &rect, 1); region = XFixesCreateRegion (xdpy, &rect, 1);
XFixesSetWindowShapeRegion (xdpy, overlay, ShapeInput, 0, 0, region); XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
} }

View File

@ -1646,6 +1646,7 @@ process_property_notify (MetaCompositorClutter *compositor,
static void static void
show_overlay_window (MetaScreen *screen, Window cow) show_overlay_window (MetaScreen *screen, Window cow)
{ {
#if 0
MetaDisplay *display = meta_screen_get_display (screen); MetaDisplay *display = meta_screen_get_display (screen);
Display *xdisplay = meta_display_get_xdisplay (display); Display *xdisplay = meta_display_get_xdisplay (display);
XserverRegion region; XserverRegion region;
@ -1656,6 +1657,7 @@ show_overlay_window (MetaScreen *screen, Window cow)
XFixesSetWindowShapeRegion (xdisplay, cow, ShapeInput, 0, 0, region); XFixesSetWindowShapeRegion (xdisplay, cow, ShapeInput, 0, 0, region);
XFixesDestroyRegion (xdisplay, region); XFixesDestroyRegion (xdisplay, region);
#endif
} }
static Window static Window
@ -1668,7 +1670,14 @@ get_output_window (MetaScreen *screen)
xroot = meta_screen_get_xroot (screen); xroot = meta_screen_get_xroot (screen);
output = XCompositeGetOverlayWindow (xdisplay, xroot); output = XCompositeGetOverlayWindow (xdisplay, xroot);
XSelectInput (xdisplay, output, ExposureMask); XSelectInput (xdisplay,
output,
FocusChangeMask |
ExposureMask |
PointerMotionMask |
PropertyChangeMask |
ButtonPressMask | ButtonReleaseMask |
KeyPressMask | KeyReleaseMask);
return output; return output;
} }
@ -1749,6 +1758,15 @@ clutter_cmp_manage_screen (MetaCompositor *compositor,
XReparentWindow (xdisplay, xwin, info->output, 0, 0); XReparentWindow (xdisplay, xwin, info->output, 0, 0);
XSelectInput (xdisplay,
xwin,
FocusChangeMask |
ExposureMask |
PointerMotionMask |
PropertyChangeMask |
ButtonPressMask | ButtonReleaseMask |
KeyPressMask | KeyReleaseMask);
info->window_group = clutter_group_new (); info->window_group = clutter_group_new ();
info->overlay_group = clutter_group_new (); info->overlay_group = clutter_group_new ();
@ -1843,6 +1861,30 @@ clutter_cmp_process_event (MetaCompositor *compositor,
event) == TRUE) event) == TRUE)
return; return;
} }
else
{
GSList *l;
MetaCompositorClutter *clc = (MetaCompositorClutter*)compositor;
l = meta_display_get_screens (clc->display);
while (l)
{
MetaScreen *screen = l->data;
MetaCompScreen *info;
info = meta_screen_get_compositor_data (screen);
if (meta_compositor_clutter_plugin_manager_xevent_filter
(info->plugin_mgr,
event) == TRUE)
{
return;
}
l = l->next;
}
}
/* /*
* This trap is so that none of the compositor functions cause * This trap is so that none of the compositor functions cause