@ -35,34 +35,32 @@
# include <clutter/x11/clutter-x11.h>
static GSList * plugin_types ;
/*
* We have one " default plugin manager " that acts for the first screen ,
* but also can be used before we open any screens , and additional
* plugin managers for each screen . ( This is ugly . Probably we should
* have one plugin manager and only make the plugins per - screen . )
*/
static MetaPluginManager * default_plugin_manager ;
static GType plugin_type = G_TYPE_NONE ;
struct MetaPluginManager
{
MetaScreen * screen ;
GList /* MetaPlugin */ * plugins ; /* TODO -- maybe use hash table */
MetaPlugin * plugin ;
} ;
void
meta_plugin_manager_set_plugin_type ( GType gtype )
{
if ( plugin_type ! = G_TYPE_NONE )
meta_fatal ( " Muffin plugin already set: %s " , g_type_name ( plugin_type ) ) ;
plugin_type = gtype ;
}
/*
* Loads the given plugin .
*/
void
meta_plugin_manager_load ( MetaPluginManager * plugin_mgr ,
const gchar * plugin_name )
meta_plugin_manager_load ( const gchar * plugin_name )
{
const gchar * dpath = MUFFIN_PLUGIN_DIR " / " ;
gchar * path ;
MetaModule * module ;
GType plugin_type ;
if ( g_path_is_absolute ( plugin_name ) )
path = g_strdup ( plugin_name ) ;
@ -81,162 +79,47 @@ meta_plugin_manager_load (MetaPluginManager *plugin_mgr,
exit ( 1 ) ;
}
plugin_type = meta_module_get_plugin_type ( module ) ;
meta_plugin_manager_register ( plugin_mgr , plugin_type ) ;
meta_plugin_manager_set_plugin_type ( meta_module_get_plugin_type ( module ) ) ;
g_type_module_unuse ( G_TYPE_MODULE ( module ) ) ;
g_free ( path ) ;
}
/*
* Registers the given plugin type
*/
LOCAL_SYMBOL void
meta_plugin_manager_register ( MetaPluginManager * plugin_mgr ,
GType plugin_type )
{
MetaPlugin * plugin ;
plugin_types = g_slist_prepend ( plugin_types , GSIZE_TO_POINTER ( plugin_type ) ) ;
plugin = g_object_new ( plugin_type , NULL ) ;
plugin_mgr - > plugins = g_list_prepend ( plugin_mgr - > plugins , plugin ) ;
}
LOCAL_SYMBOL void
meta_plugin_manager_initialize ( MetaPluginManager * plugin_mgr )
{
GList * iter ;
if ( ! plugin_mgr - > plugins )
{
/*
* If no plugins are specified , load the default plugin .
*/
meta_plugin_manager_load ( plugin_mgr , " default " ) ;
}
for ( iter = plugin_mgr - > plugins ; iter ; iter = iter - > next )
{
MetaPlugin * plugin = ( MetaPlugin * ) iter - > data ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
g_object_set ( plugin ,
" screen " , plugin_mgr - > screen ,
NULL ) ;
if ( klass - > start )
klass - > start ( plugin ) ;
}
}
static MetaPluginManager *
MetaPluginManager *
meta_plugin_manager_new ( MetaScreen * screen )
{
MetaPluginManager * plugin_mgr ;
MetaPluginClass * klass ;
MetaPlugin * plugin ;
plugin_mgr = g_new0 ( MetaPluginManager , 1 ) ;
plugin_mgr - > screen = screen ;
plugin_mgr - > plugin = plugin = g_object_new ( plugin_type , " screen " , screen , NULL ) ;
if ( screen )
g_object_set_data ( G_OBJECT ( screen ) , " meta-plugin-manager " , plugin_mgr ) ;
klass = META_PLUGIN_GET_CLASS ( plugin ) ;
return plugin_mgr ;
}
if ( klass - > start )
klass - > start ( plugin ) ;
MetaPluginManager *
meta_plugin_manager_get_default ( void )
{
if ( ! default_plugin_manager )
{
default_plugin_manager = meta_plugin_manager_new ( NULL ) ;
}
return default_plugin_manager ;
}
LOCAL_SYMBOL MetaPluginManager *
meta_plugin_manager_get ( MetaScreen * screen )
{
MetaPluginManager * plugin_mgr ;
plugin_mgr = g_object_get_data ( G_OBJECT ( screen ) , " meta-plugin-manager " ) ;
if ( plugin_mgr )
return plugin_mgr ;
if ( ! default_plugin_manager )
meta_plugin_manager_get_default ( ) ;
if ( ! default_plugin_manager - > screen )
{
/* The default plugin manager is so far unused, we can recycle it */
default_plugin_manager - > screen = screen ;
g_object_set_data ( G_OBJECT ( screen ) , " meta-plugin-manager " , default_plugin_manager ) ;
return default_plugin_manager ;
}
else
{
GSList * iter ;
GType plugin_type ;
MetaPlugin * plugin ;
plugin_mgr = meta_plugin_manager_new ( screen ) ;
for ( iter = plugin_types ; iter ; iter = iter - > next )
{
plugin_type = ( GType ) GPOINTER_TO_SIZE ( iter - > data ) ;
plugin = g_object_new ( plugin_type , " screen " , screen , NULL ) ;
plugin_mgr - > plugins = g_list_prepend ( plugin_mgr - > plugins , plugin ) ;
}
return plugin_mgr ;
}
return plugin_mgr ;
}
static void
meta_plugin_manager_kill_window_effects ( MetaPluginManager * plugin_mgr ,
MetaWindowActor * actor )
{
GList * l = plugin_mgr - > plugins ;
MetaPlugin * plugin = plugin_mgr - > plugin ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
while ( l )
{
MetaPlugin * plugin = l - > data ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
if ( ! meta_plugin_disabled ( plugin )
& & klass - > kill_window_effects )
if ( klass - > kill_window_effects )
klass - > kill_window_effects ( plugin , actor ) ;
l = l - > next ;
}
}
static void
meta_plugin_manager_kill_switch_workspace ( MetaPluginManager * plugin_mgr )
{
GList * l = plugin_mgr - > plugins ;
while ( l )
{
MetaPlugin * plugin = l - > data ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
if ( ! meta_plugin_disabled ( plugin )
& & ( meta_plugin_features ( plugin ) & META_PLUGIN_SWITCH_WORKSPACE )
& & klass - > kill_switch_workspace )
klass - > kill_switch_workspace ( plugin ) ;
l = l - > next ;
}
}
/*
* Public method that the compositor hooks into for events that require
* no additional parameters .
*
* Returns TRUE if at least one of the plugins handled the event type ( i . e . ,
* Returns TRUE if the plugin handled the event type ( i . e . ,
* if the return value is FALSE , there will be no subsequent call to the
* manager completed ( ) callback , and the compositor must ensure that any
* appropriate post - effect cleanup is carried out .
@ -246,70 +129,56 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
MetaWindowActor * actor ,
unsigned long event )
{
GList * l = plugin_mgr - > plugins ;
gboolean retval = FALSE ;
MetaDisplay * display = meta_screen_get_display ( plugin_mgr - > screen ) ;
MetaPlugin * plugin = plugin_mgr - > plugin ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
MetaDisplay * display = meta_screen_get_display ( plugin_mgr - > screen ) ;
gboolean retval = FALSE ;
if ( display - > display_opening )
return FALSE ;
if ( display - > display_opening )
return FALSE ;
while ( l )
switch ( event )
{
MetaPlugin * plugin = l - > data ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
case META_PLUGIN_MINIMIZE :
if ( klass - > minimize )
{
retval = TRUE ;
meta_plugin_manager_kill_window_effects ( plugin_mgr , actor ) ;
if ( ! meta_plugin_disabled ( plugin ) & &
( meta_plugin_features ( plugin ) & event ) )
{
retval = TRUE ;
_meta_plugin_effect_started ( plugin ) ;
klass - > minimize ( plugin , actor ) ;
}
break ;
case META_PLUGIN_MAP :
if ( klass - > map )
{
retval = TRUE ;
meta_plugin_manager_kill_window_effects ( plugin_mgr , actor ) ;
switch ( event )
_meta_plugin_effect_started ( plugin ) ;
klass - > map ( plugin , actor ) ;
}
break ;
case META_PLUGIN_DESTROY :
if ( klass - > destroy )
{
case META_PLUGIN_MINIMIZE :
if ( klass - > minimize )
{
meta_plugin_manager_kill_window_effects (
plugin_mgr ,
actor ) ;
_meta_plugin_effect_started ( plugin ) ;
klass - > minimize ( plugin , actor ) ;
}
break ;
case META_PLUGIN_MAP :
if ( klass - > map )
{
meta_plugin_manager_kill_window_effects (
plugin_mgr ,
actor ) ;
_meta_plugin_effect_started ( plugin ) ;
klass - > map ( plugin , actor ) ;
}
break ;
case META_PLUGIN_DESTROY :
if ( klass - > destroy )
{
_meta_plugin_effect_started ( plugin ) ;
klass - > destroy ( plugin , actor ) ;
}
break ;
default :
g_warning ( " Incorrect handler called for event %lu " , event ) ;
retval = TRUE ;
_meta_plugin_effect_started ( plugin ) ;
klass - > destroy ( plugin , actor ) ;
}
}
l = l - > next ;
break ;
default :
g_warning ( " Incorrect handler called for event %lu " , event ) ;
}
return retval ;
return retval ;
}
/*
* The public method that the compositor hooks into for maximize and unmaximize
* events .
*
* Returns TRUE if at least one of the plugins handled the event type ( i . e . ,
* Returns TRUE if the plugin handled the event type ( i . e . ,
* if the return value is FALSE , there will be no subsequent call to the
* manager completed ( ) callback , and the compositor must ensure that any
* appropriate post - effect cleanup is carried out .
@ -323,77 +192,67 @@ meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr,
gint target_width ,
gint target_height )
{
GList * l = plugin_mgr - > plugins ;
gboolean retval = FALSE ;
MetaDisplay * display = meta_screen_get_display ( plugin_mgr - > screen ) ;
MetaPlugin * plugin = plugin_mgr - > plugin ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
MetaDisplay * display = meta_screen_get_display ( plugin_mgr - > screen ) ;
gboolean retval = FALSE ;
if ( display - > display_opening )
return FALSE ;
if ( display - > display_opening )
return FALSE ;
while ( l )
switch ( event )
{
MetaPlugin * plugin = l - > data ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
if ( ! meta_plugin_disabled ( plugin ) & &
( meta_plugin_features ( plugin ) & event ) )
{
retval = TRUE ;
switch ( event )
case META_PLUGIN_MAXIMIZE :
if ( klass - > maximize )
{
case META_PLUGIN_MAXIMIZE :
if ( klass - > maximize )
{
meta_plugin_manager_kill_window_effects (
plugin_mgr ,
actor ) ;
_meta_plugin_effect_started ( plugin ) ;
klass - > maximize ( plugin , actor ,
target_x , target_y ,
target_width , target_height ) ;
}
break ;
case META_PLUGIN_UNMAXIMIZE :
if ( klass - > unmaximize )
{
meta_plugin_manager_kill_window_effects (
plugin_mgr ,
actor ) ;
_meta_plugin_effect_started ( plugin ) ;
klass - > unmaximize ( plugin , actor ,
target_x , target_y ,
target_width , target_height ) ;
}
break ;
case META_PLUGIN_TILE :
if ( klass - > tile )
{
meta_plugin_manager_kill_window_effects ( plugin_mgr ,
actor ) ;
_meta_plugin_effect_started ( plugin ) ;
klass - > tile ( plugin , actor ,
retval = TRUE ;
meta_plugin_manager_kill_window_effects (
plugin_mgr ,
actor ) ;
_meta_plugin_effect_started ( plugin ) ;
klass - > maximize ( plugin , actor ,
target_x , target_y ,
target_width , target_height ) ;
}
break ;
default :
g_warning ( " Incorrect handler called for event %lu " , event ) ;
}
}
break ;
case META_PLUGIN_UNMAXIMIZE :
if ( klass - > unmaximize )
{
retval = TRUE ;
meta_plugin_manager_kill_window_effects (
plugin_mgr ,
actor ) ;
l = l - > next ;
_meta_plugin_effect_started ( plugin ) ;
klass - > unmaximize ( plugin , actor ,
target_x , target_y ,
target_width , target_height ) ;
}
break ;
case META_PLUGIN_TILE :
if ( klass - > tile )
{
retval = TRUE ;
meta_plugin_manager_kill_window_effects ( plugin_mgr ,
actor ) ;
_meta_plugin_effect_started ( plugin ) ;
klass - > tile ( plugin , actor ,
target_x , target_y ,
target_width , target_height ) ;
}
break ;
default :
g_warning ( " Incorrect handler called for event %lu " , event ) ;
}
return retval ;
return retval ;
}
/*
* The public method that the compositor hooks into for desktop switching .
*
* Returns TRUE if at least one of the plugins handled the event type ( i . e . ,
* Returns TRUE if the plugin handled the event type ( i . e . ,
* if the return value is FALSE , there will be no subsequent call to the
* manager completed ( ) callback , and the compositor must ensure that any
* appropriate post - effect cleanup is carried out .
@ -404,41 +263,29 @@ meta_plugin_manager_switch_workspace (MetaPluginManager *plugin_mgr,
gint to ,
MetaMotionDirection direction )
{
GList * l = plugin_mgr - > plugins ;
gboolean retval = FALSE ;
MetaDisplay * display = meta_screen_get_display ( plugin_mgr - > screen ) ;
MetaPlugin * plugin = plugin_mgr - > plugin ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
MetaDisplay * display = meta_screen_get_display ( plugin_mgr - > screen ) ;
gboolean retval = FALSE ;
if ( display - > display_opening )
return FALSE ;
if ( display - > display_opening )
return FALSE ;
while ( l )
if ( klass - > switch_workspace )
{
MetaPlugin * plugin = l - > data ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
if ( ! meta_plugin_disabled ( plugin ) & &
( meta_plugin_features ( plugin ) & META_PLUGIN_SWITCH_WORKSPACE ) )
{
if ( klass - > switch_workspace )
{
retval = TRUE ;
meta_plugin_manager_kill_switch_workspace ( plugin_mgr ) ;
retval = TRUE ;
_meta_plugin_effect_started ( plugin ) ;
klass - > switch_workspace ( plugin , from , to , direction ) ;
}
}
l = l - > next ;
_meta_plugin_effect_started ( plugin ) ;
klass - > switch_workspace ( plugin , from , to , direction ) ;
}
return retval ;
return retval ;
}
/*
* The public method that the compositor hooks into for desktop switching .
*
* Returns TRUE if at least one of the plugins handled the event type ( i . e . ,
* Returns TRUE if the plugin handled the event type ( i . e . ,
* if the return value is FALSE , there will be no subsequent call to the
* manager completed ( ) callback , and the compositor must ensure that any
* appropriate post - effect cleanup is carried out .
@ -447,49 +294,104 @@ LOCAL_SYMBOL gboolean
meta_plugin_manager_xevent_filter ( MetaPluginManager * plugin_mgr ,
XEvent * xev )
{
GList * l ;
gboolean have_plugin_xevent_func ;
MetaPlugin * plugin = plugin_mgr - > plugin ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
if ( ! plugin_mgr )
return FALSE ;
l = plugin_mgr - > plugins ;
/* We need to make sure that clutter gets certain events, like
* ConfigureNotify on the stage window . If there is a plugin that
* provides an xevent_filter function , then it ' s the responsibility
* of that plugin to pass events to Clutter . Otherwise , we send the
* event directly to Clutter ourselves .
*
* What happens if there are two plugins with xevent_filter functions
* is undefined ; in general , multiple competing plugins are something
* we don ' t support well or care much about .
*
* FIXME : Really , we should just always handle sending the event to
* clutter if a plugin doesn ' t report the event as handled by
* returning TRUE , but it doesn ' t seem worth breaking compatibility
* of the plugin interface right now to achieve this ; the way it is
* now works fine in practice .
*/
have_plugin_xevent_func = FALSE ;
if ( klass - > xevent_filter )
return klass - > xevent_filter ( plugin , xev ) ;
else
return clutter_x11_handle_event ( xev ) ! = CLUTTER_X11_FILTER_CONTINUE ;
}
gboolean
meta_plugin_manager_show_tile_preview ( MetaPluginManager * plugin_mgr ,
MetaWindow * window ,
MetaRectangle * tile_rect ,
int tile_monitor_number ,
guint snap_queued )
{
MetaPlugin * plugin = plugin_mgr - > plugin ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
MetaDisplay * display = meta_screen_get_display ( plugin_mgr - > screen ) ;
if ( display - > display_opening )
return FALSE ;
while ( l )
if ( klass - > show_tile_preview )
{
MetaPlugin * plugin = l - > data ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
klass - > show_tile_preview ( plugin , window , tile_rect , tile_monitor_number , snap_queued ) ;
return TRUE ;
}
if ( klass - > xevent_filter )
{
have_plugin_xevent_func = TRUE ;
if ( klass - > xevent_filter ( plugin , xev ) = = TRUE )
return TRUE ;
}
return FALSE ;
}
l = l - > next ;
gboolean
meta_plugin_manager_hide_tile_preview ( MetaPluginManager * plugin_mgr )
{
MetaPlugin * plugin = plugin_mgr - > plugin ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
MetaDisplay * display = meta_screen_get_display ( plugin_mgr - > screen ) ;
if ( display - > display_opening )
return FALSE ;
if ( klass - > hide_tile_preview )
{
klass - > hide_tile_preview ( plugin ) ;
return TRUE ;
}
if ( ! have_plugin_xevent_func )
return clutter_x11_handle_event ( xev ) ! = CLUTTER_X11_FILTER_CONTINUE ;
return FALSE ;
}
gboolean
meta_plugin_manager_show_hud_preview ( MetaPluginManager * plugin_mgr ,
guint current_proximity_zone ,
MetaRectangle * work_area ,
guint snap_queued )
{
MetaPlugin * plugin = plugin_mgr - > plugin ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
MetaDisplay * display = meta_screen_get_display ( plugin_mgr - > screen ) ;
if ( display - > display_opening )
return FALSE ;
if ( klass - > show_hud_preview )
{
klass - > show_hud_preview ( plugin , current_proximity_zone ,
work_area , snap_queued ) ;
return TRUE ;
}
return FALSE ;
}
return FALSE ;
gboolean
meta_plugin_manager_hide_hud_preview ( MetaPluginManager * plugin_mgr )
{
MetaPlugin * plugin = plugin_mgr - > plugin ;
MetaPluginClass * klass = META_PLUGIN_GET_CLASS ( plugin ) ;
MetaDisplay * display = meta_screen_get_display ( plugin_mgr - > screen ) ;
if ( display - > display_opening )
return FALSE ;
if ( klass - > hide_hud_preview )
{
klass - > hide_hud_preview ( plugin ) ;
return TRUE ;
}
return FALSE ;
}