[gnome-panel] panel: Port lockdown to GSettings



commit bb64244a00e67e8b12c0ad415817335aece82e29
Author: Vincent Untz <vuntz gnome org>
Date:   Thu Mar 24 12:40:53 2011 +0100

    panel: Port lockdown to GSettings

 gnome-panel/applet.c                  |   88 +++--
 gnome-panel/applet.h                  |    2 -
 gnome-panel/gnome-desktop-item-edit.c |    2 +-
 gnome-panel/launcher.c                |    6 +-
 gnome-panel/main.c                    |    4 -
 gnome-panel/menu.c                    |    6 +-
 gnome-panel/panel-action-button.c     |   33 +-
 gnome-panel/panel-addto.c             |    8 +-
 gnome-panel/panel-applet-frame.c      |   39 +-
 gnome-panel/panel-applet-frame.h      |    2 -
 gnome-panel/panel-context-menu.c      |    5 +-
 gnome-panel/panel-lockdown.c          |  707 ++++++++++++++++++---------------
 gnome-panel/panel-lockdown.h          |   72 +++-
 gnome-panel/panel-menu-bar.c          |    2 +-
 gnome-panel/panel-menu-button.c       |   26 +--
 gnome-panel/panel-menu-items.c        |  125 +++----
 gnome-panel/panel-profile.c           |    2 +-
 gnome-panel/panel-run-dialog.c        |    2 +-
 gnome-panel/panel-schemas.h           |   10 +
 gnome-panel/panel-toplevel.c          |    2 +-
 gnome-panel/panel-util.c              |   11 +-
 gnome-panel/panel-util.h              |    1 -
 gnome-panel/panel-widget.c            |   15 +-
 gnome-panel/panel.c                   |   50 ++-
 24 files changed, 647 insertions(+), 573 deletions(-)
---
diff --git a/gnome-panel/applet.c b/gnome-panel/applet.c
index e5dbd13..a2251c4 100644
--- a/gnome-panel/applet.c
+++ b/gnome-panel/applet.c
@@ -147,31 +147,6 @@ panel_applet_recreate_menu (AppletInfo *info)
 }
 
 static void
-panel_applet_recreate_edit_menu (AppletInfo *info)
-{
-	if (info->edit_menu) {
-		if (gtk_widget_get_visible (info->edit_menu))
-			gtk_menu_shell_deactivate (GTK_MENU_SHELL (info->edit_menu));
-
-		g_signal_handlers_disconnect_by_func (info->edit_menu,
-						      G_CALLBACK (applet_menu_show), info);
-		g_signal_handlers_disconnect_by_func (info->edit_menu,
-						      G_CALLBACK (applet_menu_deactivate), info);
-		g_object_unref (info->edit_menu);
-		info->edit_menu = NULL;
-	}
-
-	panel_applet_get_edit_menu (info);
-}
-
-static void
-panel_applet_recreate_menus (AppletInfo *info)
-{
-	panel_applet_recreate_menu (info);
-	panel_applet_recreate_edit_menu (info);
-}
-
-static void
 applet_remove_callback (GtkWidget  *widget,
 			AppletInfo *info)
 {
@@ -430,6 +405,15 @@ panel_applet_create_bare_menu (AppletInfo *info)
 	return menu;
 }
 
+static void
+panel_applet_menu_lockdown_changed (PanelLockdown *lockdown,
+				    gpointer       user_data)
+{
+	AppletInfo *info = user_data;
+
+	panel_applet_recreate_menu (info);
+}
+
 static GtkWidget *
 panel_applet_get_menu (AppletInfo *info)
 {
@@ -466,10 +450,36 @@ panel_applet_get_menu (AppletInfo *info)
 
 	info->menu = menu;
 
+	panel_lockdown_on_notify (panel_lockdown_get (),
+				  NULL,
+				  G_OBJECT (info->menu),
+				  panel_applet_menu_lockdown_changed,
+				  info);
+
 	return info->menu;
 }
 
-GtkWidget *
+static void
+panel_applet_edit_menu_lockdown_changed (PanelLockdown *lockdown,
+					 gpointer       user_data)
+{
+	AppletInfo *info = user_data;
+
+	if (!panel_lockdown_get_panels_locked_down (lockdown))
+		return;
+
+	if (info->edit_menu) {
+		if (gtk_widget_get_visible (info->edit_menu))
+			gtk_menu_shell_deactivate (GTK_MENU_SHELL (info->edit_menu));
+
+                g_signal_handlers_disconnect_by_func (info->edit_menu,
+						      G_CALLBACK (applet_menu_deactivate), info);
+		gtk_widget_destroy (info->edit_menu);
+		info->edit_menu = NULL;
+	}
+}
+
+static GtkWidget *
 panel_applet_get_edit_menu (AppletInfo *info)
 {
 	GtkWidget   *menu;
@@ -482,7 +492,7 @@ panel_applet_get_edit_menu (AppletInfo *info)
 	if (info->edit_menu)
 		return info->edit_menu;
 
-	if (panel_lockdown_get_locked_down ())
+	if (panel_lockdown_get_panels_locked_down_s ())
 		return NULL;
 
 	menu = panel_applet_create_bare_menu (info);
@@ -511,6 +521,12 @@ panel_applet_get_edit_menu (AppletInfo *info)
 
 	info->edit_menu = menu;
 
+	panel_lockdown_on_notify (panel_lockdown_get (),
+				  "panels-locked-down",
+				  G_OBJECT (info->edit_menu),
+				  panel_applet_edit_menu_lockdown_changed,
+				  info);
+
 	return info->edit_menu;
 }
 
@@ -725,11 +741,10 @@ panel_applet_destroy (GtkWidget  *widget,
 	queued_position_saves =
 		g_slist_remove (queued_position_saves, info);
 
-	if (info->type != PANEL_OBJECT_APPLET)
-		panel_lockdown_notify_remove (G_CALLBACK (panel_applet_recreate_menus),
-					      info);
-
 	if (info->menu) {
+		if (gtk_widget_get_visible (info->menu))
+			gtk_menu_shell_deactivate (GTK_MENU_SHELL (info->menu));
+
                 g_signal_handlers_disconnect_by_func (info->menu,
 						      G_CALLBACK (applet_menu_show), info);
                 g_signal_handlers_disconnect_by_func (info->menu,
@@ -739,6 +754,9 @@ panel_applet_destroy (GtkWidget  *widget,
 	info->menu = NULL;
 
 	if (info->edit_menu) {
+		if (gtk_widget_get_visible (info->edit_menu))
+			gtk_menu_shell_deactivate (GTK_MENU_SHELL (info->edit_menu));
+
                 g_signal_handlers_disconnect_by_func (info->edit_menu,
 						      G_CALLBACK (applet_menu_show), info);
                 g_signal_handlers_disconnect_by_func (info->edit_menu,
@@ -1244,10 +1262,6 @@ panel_applet_register (GtkWidget       *applet,
 
 	g_object_set_data (G_OBJECT (applet), "applet_info", info);
 
-	if (type != PANEL_OBJECT_APPLET)
-		panel_lockdown_notify_add (G_CALLBACK (panel_applet_recreate_menus),
-					   info);
-
 	registered_applets = g_slist_append (registered_applets, info);
 
 	if (panel_widget_add (panel, applet, pos, exactpos) == -1 &&
@@ -1319,7 +1333,9 @@ panel_applet_can_freely_move (AppletInfo *applet)
 	PanelGConfKeyType  key_type;
 	const char        *key;
 
-	if (panel_lockdown_get_locked_down ())
+	/* if we check for more lockdown than this, then we'll need to update
+	 * callers that use panel_lockdown_on_notify() */
+	if (panel_lockdown_get_panels_locked_down_s ())
 		return FALSE;
 
 	client  = panel_gconf_get_client ();
diff --git a/gnome-panel/applet.h b/gnome-panel/applet.h
index d3f6e9a..129ebc8 100644
--- a/gnome-panel/applet.h
+++ b/gnome-panel/applet.h
@@ -92,8 +92,6 @@ int         panel_applet_get_position    (AppletInfo *applet);
    (position, toplevel_id, panel_right_stick) */
 gboolean    panel_applet_can_freely_move (AppletInfo *applet);
 
-GtkWidget  *panel_applet_get_edit_menu (AppletInfo *info);
-
 void        panel_applet_menu_set_recurse (GtkMenu     *menu,
 					   const gchar *key,
 					   gpointer     data);
diff --git a/gnome-panel/gnome-desktop-item-edit.c b/gnome-panel/gnome-desktop-item-edit.c
index 68c1dba..ec315ca 100644
--- a/gnome-panel/gnome-desktop-item-edit.c
+++ b/gnome-panel/gnome-desktop-item-edit.c
@@ -17,7 +17,7 @@ GSList *panel_applet_list_applets (void) { return NULL; }
 #include "panel-gconf.h"
 GConfClient *panel_gconf_get_client (void) { return NULL; }
 #include "panel-lockdown.h"
-gboolean panel_lockdown_get_disable_lock_screen (void) { return FALSE; }
+gboolean panel_lockdown_get_disable_lock_screen_s (void) { return FALSE; }
 #include "panel-bindings.h"
 guint panel_bindings_get_mouse_button_modifier_keymask (void) { return 0; }
 #include "panel-toplevel.h"
diff --git a/gnome-panel/launcher.c b/gnome-panel/launcher.c
index 7b035e8..7188d7d 100644
--- a/gnome-panel/launcher.c
+++ b/gnome-panel/launcher.c
@@ -758,8 +758,8 @@ launcher_properties (Launcher  *launcher)
 static gboolean
 lancher_properties_enabled (void)
 {
-	if (panel_lockdown_get_locked_down () ||
-	    panel_lockdown_get_disable_command_line ())
+	if (panel_lockdown_get_panels_locked_down_s () ||
+	    panel_lockdown_get_disable_command_line_s ())
 		return FALSE;
 
 	return TRUE;
@@ -880,7 +880,7 @@ ask_about_launcher (const char  *file,
 	GtkWidget *dialog;
 	GKeyFile  *key_file;
 
-	if (panel_lockdown_get_disable_command_line ())
+	if (panel_lockdown_get_disable_command_line_s ())
 		return;
 
 	dialog = panel_ditem_editor_new (NULL, NULL, NULL,
diff --git a/gnome-panel/main.c b/gnome-panel/main.c
index 9200c23..624961f 100644
--- a/gnome-panel/main.c
+++ b/gnome-panel/main.c
@@ -26,7 +26,6 @@
 #include "panel-session.h"
 #include "panel-stock-icons.h"
 #include "panel-action-protocol.h"
-#include "panel-lockdown.h"
 #include "panel-icon-names.h"
 #include "xstuff.h"
 
@@ -98,7 +97,6 @@ main (int argc, char **argv)
 	panel_multiscreen_init ();
 	panel_init_stock_icons_and_items ();
 
-	panel_lockdown_init ();
 	panel_profile_load ();
 
 	xstuff_init ();
@@ -113,8 +111,6 @@ main (int argc, char **argv)
 
 	gtk_main ();
 
-	panel_lockdown_finalize ();
-
 	panel_cleanup_do ();
 
 	return 0;
diff --git a/gnome-panel/menu.c b/gnome-panel/menu.c
index 1298589..51c68d2 100644
--- a/gnome-panel/menu.c
+++ b/gnome-panel/menu.c
@@ -834,7 +834,7 @@ setup_uri_drag (GtkWidget  *menuitem,
 		{ "text/uri-list", 0, 0 }
 	};
 
-	if (panel_lockdown_get_locked_down ())
+	if (panel_lockdown_get_panels_locked_down_s ())
 		return;
 
 	gtk_drag_source_set (menuitem,
@@ -864,7 +864,7 @@ setup_internal_applet_drag (GtkWidget             *menuitem,
 		{ "application/x-panel-applet-internal", 0, 0 }
 	};
 
-	if (panel_lockdown_get_locked_down ())
+	if (panel_lockdown_get_panels_locked_down_s ())
 		return;
 
 	gtk_drag_source_set (menuitem,
@@ -1115,7 +1115,7 @@ create_menuitem (GtkWidget          *menu,
 	g_signal_connect_after (menuitem, "button_press_event",
 				G_CALLBACK (menu_dummy_button_press_event), NULL);
 
-	if (!panel_lockdown_get_locked_down ()) {
+	if (!panel_lockdown_get_panels_locked_down_s ()) {
 		static GtkTargetEntry menu_item_targets[] = {
 			{ "text/uri-list", 0, 0 }
 		};
diff --git a/gnome-panel/panel-action-button.c b/gnome-panel/panel-action-button.c
index e3f96f3..5a38dbf 100644
--- a/gnome-panel/panel-action-button.c
+++ b/gnome-panel/panel-action-button.c
@@ -88,14 +88,14 @@ static GConfEnumStringPair panel_action_type_map [] = {
 static void
 panel_action_lock_screen (GtkWidget *widget)
 {
-	panel_lock_screen (gtk_widget_get_screen (widget));
+	panel_lock_screen_action (gtk_widget_get_screen (widget), "lock");
 }
 
 static gboolean
 screensaver_properties_enabled (void)
 {
-	if (panel_lockdown_get_locked_down () ||
-	    panel_lockdown_get_disable_lock_screen ())
+	if (panel_lockdown_get_panels_locked_down_s () ||
+	    panel_lockdown_get_disable_lock_screen_s ())
 		return FALSE;
 
 	return panel_lock_screen_action_available ("prefs");
@@ -104,7 +104,7 @@ screensaver_properties_enabled (void)
 static gboolean
 screensaver_enabled (void)
 {
-	if (panel_lockdown_get_disable_lock_screen ())
+	if (panel_lockdown_get_disable_lock_screen_s ())
 		return FALSE;
 
 	return panel_lock_screen_action_available ("lock");
@@ -190,7 +190,7 @@ panel_action_shutdown_reboot_is_disabled (void)
 {
 	PanelSessionManager *manager;
 
-	if (panel_lockdown_get_disable_log_out())
+	if (panel_lockdown_get_disable_log_out_s ())
 		return TRUE;
 
 	manager = panel_session_manager_get ();
@@ -313,7 +313,7 @@ static PanelAction actions [] = {
 		N_("Log out of this session to log in as a different user"),
 		"ACTION:logout:NEW",
 		panel_action_logout, NULL, NULL,
-		panel_lockdown_get_disable_log_out
+		panel_lockdown_get_disable_log_out_s
 	},
 	{
 		PANEL_ACTION_RUN,
@@ -322,7 +322,7 @@ static PanelAction actions [] = {
 		N_("Run an application by typing a command or choosing from a list"),
 		"ACTION:run:NEW",
 		panel_action_run_program, NULL, NULL,
-		panel_lockdown_get_disable_command_line
+		panel_lockdown_get_disable_command_line_s
 	},
 	{
 		PANEL_ACTION_SEARCH,
@@ -339,7 +339,7 @@ static PanelAction actions [] = {
 		N_("Force a misbehaving application to quit"),
 		"ACTION:force-quit:NEW",
 		panel_action_force_quit, NULL, NULL,
-		panel_lockdown_get_disable_force_quit
+		panel_lockdown_get_disable_force_quit_s
 	},
 	{
 		PANEL_ACTION_CONNECT_SERVER,
@@ -425,8 +425,11 @@ panel_action_get_drag_id (PanelActionButtonType type)
 }
 
 static void
-panel_action_button_update_sensitivity (PanelActionButton *button)
+panel_action_button_update_sensitivity (PanelLockdown *lockdown,
+					gpointer       user_data)
 {
+	PanelActionButton *button = user_data;
+
 	if (actions [button->priv->type].is_disabled)
 		button_widget_set_activatable (BUTTON_WIDGET (button),
 					       !actions [button->priv->type].is_disabled ());
@@ -440,9 +443,6 @@ panel_action_button_finalize (GObject *object)
 	button->priv->info = NULL;
 	button->priv->type = PANEL_ACTION_NONE;
 
-	panel_lockdown_notify_remove (G_CALLBACK (panel_action_button_update_sensitivity),
-				      button);
-
 	gconf_client_notify_remove (panel_gconf_get_client (),
 				    button->priv->gconf_notify);
 	button->priv->gconf_notify = 0;
@@ -613,7 +613,7 @@ panel_action_button_set_type (PanelActionButton     *button,
 				     _(actions [type].tooltip));
 	panel_a11y_set_atk_name_desc (GTK_WIDGET (button), _(actions [type].tooltip), NULL);
 
-	panel_action_button_update_sensitivity (button);
+	panel_action_button_update_sensitivity (panel_lockdown_get (), button);
 }
 
 static void
@@ -651,8 +651,11 @@ panel_action_button_connect_to_gconf (PanelActionButton *button)
 					 (GConfClientNotifyFunc) panel_action_button_type_changed,
 					 button, NULL, NULL);
 
-	panel_lockdown_notify_add (G_CALLBACK (panel_action_button_update_sensitivity),
-				   button);
+	panel_lockdown_on_notify (panel_lockdown_get (),
+				  NULL,
+				  G_OBJECT (button),
+				  panel_action_button_update_sensitivity,
+				  button);
 }
 
 static void
diff --git a/gnome-panel/panel-addto.c b/gnome-panel/panel-addto.c
index 4e77536..7f5e4c9 100644
--- a/gnome-panel/panel-addto.c
+++ b/gnome-panel/panel-addto.c
@@ -312,7 +312,7 @@ panel_addto_setup_drag (GtkTreeView          *tree_view,
 			const GtkTargetEntry *target,
 			const char           *text)
 {
-	if (!text || panel_lockdown_get_locked_down ())
+	if (!text || panel_lockdown_get_panels_locked_down_s ())
 		return;
 	
 	gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (tree_view),
@@ -387,7 +387,9 @@ panel_addto_query_applets (GSList *list)
 		description = panel_applet_info_get_description (info);
 		icon = panel_applet_info_get_icon (info);
 
-		if (!name || panel_lockdown_is_applet_disabled (iid)) {
+		if (!name ||
+		    panel_lockdown_is_applet_disabled (panel_lockdown_get (),
+						       iid)) {
 			continue;
 		}
 
@@ -464,7 +466,7 @@ panel_addto_append_special_applets (PanelAddtoDialog *dialog,
 		}
 
 		if (special_addto_items [i].type == PANEL_ADDTO_LAUNCHER_NEW
-		    && panel_lockdown_get_disable_command_line ())
+		    && panel_lockdown_get_disable_command_line_s ())
 			continue;
 		
 		panel_addto_append_item (dialog, model, &special_addto_items [i]);
diff --git a/gnome-panel/panel-applet-frame.c b/gnome-panel/panel-applet-frame.c
index a7ce389..992b0be 100644
--- a/gnome-panel/panel-applet-frame.c
+++ b/gnome-panel/panel-applet-frame.c
@@ -416,9 +416,6 @@ panel_applet_frame_finalize (GObject *object)
 
 	panel_applets_manager_factory_deactivate (frame->priv->iid);
 
-	panel_lockdown_notify_remove (G_CALLBACK (panel_applet_frame_sync_menu_state),
-				      frame);
-
 	g_free (frame->priv->iid);
 	frame->priv->iid = NULL;
 
@@ -460,19 +457,21 @@ panel_applet_frame_init_properties (PanelAppletFrame *frame)
 	PANEL_APPLET_FRAME_GET_CLASS (frame)->init_properties (frame);
 }
 
-void
-panel_applet_frame_sync_menu_state (PanelAppletFrame *frame)
+static void
+panel_applet_frame_sync_menu_state (PanelLockdown *lockdown,
+				    gpointer       user_data)
 {
-	PanelWidget *panel_widget;
-	gboolean     locked_down;
-	gboolean     movable;
-	gboolean     removable;
+	PanelAppletFrame *frame = PANEL_APPLET_FRAME (user_data);
+	PanelWidget      *panel_widget;
+	gboolean          locked_down;
+	gboolean          movable;
+	gboolean          removable;
 
 	panel_widget = PANEL_WIDGET (gtk_widget_get_parent (GTK_WIDGET (frame)));
 
 	movable = panel_applet_can_freely_move (frame->priv->applet_info);
 	removable = panel_profile_id_lists_are_writable ();
-	locked_down = panel_lockdown_get_locked_down ();
+	locked_down = panel_lockdown_get_panels_locked_down_s ();
 
 	PANEL_APPLET_FRAME_GET_CLASS (frame)->sync_menu_state (frame, movable, removable, locked_down);
 }
@@ -573,11 +572,15 @@ _panel_applet_frame_activated (PanelAppletFrame           *frame,
 	panel_widget_set_applet_size_constrained (frame->priv->panel,
 						  GTK_WIDGET (frame), TRUE);
 
-	panel_applet_frame_sync_menu_state (frame);
-	panel_applet_frame_init_properties (frame);
 
-	panel_lockdown_notify_add (G_CALLBACK (panel_applet_frame_sync_menu_state),
-				   frame);
+	panel_lockdown_on_notify (panel_lockdown_get (),
+				  NULL,
+				  G_OBJECT (frame),
+				  panel_applet_frame_sync_menu_state,
+				  frame);
+	panel_applet_frame_sync_menu_state (panel_lockdown_get (), frame);
+
+	panel_applet_frame_init_properties (frame);
 
 	panel_applet_stop_loading (frame_act->id);
 	panel_applet_frame_activating_free (frame_act);
@@ -836,7 +839,7 @@ panel_applet_frame_activating_get_size (PanelAppletFrameActivating *frame_act)
 gboolean
 panel_applet_frame_activating_get_locked_down (PanelAppletFrameActivating *frame_act)
 {
-	return panel_lockdown_get_locked_down ();
+	return panel_lockdown_get_panels_locked_down_s ();
 }
 
 gchar *
@@ -853,7 +856,7 @@ panel_applet_frame_loading_failed_response (GtkWidget *dialog,
 	gtk_widget_destroy (dialog);
 
 	if (response == LOADING_FAILED_RESPONSE_DELETE &&
-	    !panel_lockdown_get_locked_down () &&
+	    !panel_lockdown_get_panels_locked_down_s () &&
 	    panel_profile_id_lists_are_writable ()) {
 		GSList *item;
 
@@ -883,7 +886,7 @@ panel_applet_frame_loading_failed (const char  *iid,
 	no_reload_applets = g_slist_prepend (no_reload_applets,
 					     g_strdup (id));
 
-	locked_down = panel_lockdown_get_locked_down ();
+	locked_down = panel_lockdown_get_panels_locked_down_s ();
 
 	problem_txt = g_strdup_printf (_("The panel encountered a problem "
 					 "while loading \"%s\"."),
@@ -950,7 +953,7 @@ panel_applet_frame_load (const gchar *iid,
 		return;
 	}
 
-	if (panel_lockdown_is_applet_disabled (iid)) {
+	if (panel_lockdown_is_applet_disabled (panel_lockdown_get (), iid)) {
 		panel_applet_stop_loading (id);
 		return;
 	}
diff --git a/gnome-panel/panel-applet-frame.h b/gnome-panel/panel-applet-frame.h
index 458d961..2b366a7 100644
--- a/gnome-panel/panel-applet-frame.h
+++ b/gnome-panel/panel-applet-frame.h
@@ -87,8 +87,6 @@ void  panel_applet_frame_load_from_gconf    (PanelWidget         *panel_widget,
 					     int                  position,
 					     const char          *id);
 
-void  panel_applet_frame_sync_menu_state    (PanelAppletFrame    *frame);
-
 void  panel_applet_frame_change_orientation (PanelAppletFrame    *frame,
 					     PanelOrientation     orientation);
 
diff --git a/gnome-panel/panel-context-menu.c b/gnome-panel/panel-context-menu.c
index e74dc4a..9d12bc4 100644
--- a/gnome-panel/panel-context-menu.c
+++ b/gnome-panel/panel-context-menu.c
@@ -106,7 +106,7 @@ panel_context_menu_setup_delete_panel_item (GtkWidget *menu,
 
 	sensitive =
 		!panel_toplevel_is_last (panel_widget->toplevel) &&
-		!panel_lockdown_get_locked_down () &&
+		!panel_lockdown_get_panels_locked_down_s () &&
 		panel_profile_id_lists_are_writable ();
 
 	gtk_widget_set_sensitive (menuitem, sensitive);
@@ -172,10 +172,11 @@ panel_context_menu_create (PanelWidget *panel)
 {
 	GtkWidget *retval;
 
-	if (panel_lockdown_get_locked_down ())
+	if (panel_lockdown_get_panels_locked_down_s ())
 		return NULL;
 
 	retval = create_empty_menu ();
+
 	gtk_widget_set_name (retval, "gnome-panel-context-menu");
 
 	panel_context_menu_build_edition (panel, retval);
diff --git a/gnome-panel/panel-lockdown.c b/gnome-panel/panel-lockdown.c
index 7dbfa7f..efc7401 100644
--- a/gnome-panel/panel-lockdown.c
+++ b/gnome-panel/panel-lockdown.c
@@ -1,6 +1,8 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* vim: set sw=8 et: */
 /*
- * Copyright (C) 2004 Sun Microsystems, Inc.
+ * panel-lockdown.c: a lockdown tracker.
+ *
+ * Copyright (C) 2011 Novell, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -18,433 +20,482 @@
  * 02111-1307, USA.
  *
  * Authors:
- *      Matt Keenan  <matt keenan sun com>
- *      Mark McLoughlin  <mark skynet ie>
+ *      Vincent Untz <vuntz gnome org>
  */
 
-#include <config.h>
-
-#include "panel-lockdown.h"
-
-#include <string.h>
-#include "panel-gconf.h"
-
-#define N_LISTENERS 6
+#include <libpanel-util/panel-cleanup.h>
 
-#define PANEL_GLOBAL_LOCKDOWN_DIR    "/apps/panel/global"
-#define DESKTOP_GNOME_LOCKDOWN_DIR   "/desktop/gnome/lockdown"
-#define PANEL_GLOBAL_LOCKED_DOWN_KEY PANEL_GLOBAL_LOCKDOWN_DIR  "/locked_down"
-#define DISABLE_COMMAND_LINE_KEY     DESKTOP_GNOME_LOCKDOWN_DIR "/disable_command_line"
-#define DISABLE_LOCK_SCREEN_KEY      DESKTOP_GNOME_LOCKDOWN_DIR  "/disable_lock_screen"
-#define DISABLE_LOG_OUT_KEY          PANEL_GLOBAL_LOCKDOWN_DIR  "/disable_log_out"
-#define DISABLE_FORCE_QUIT_KEY       PANEL_GLOBAL_LOCKDOWN_DIR  "/disable_force_quit"
-#define DISABLED_APPLETS_KEY         PANEL_GLOBAL_LOCKDOWN_DIR  "/disabled_applets"
+#include "panel-schemas.h"
 
-typedef struct {
-        guint   initialized : 1;
-
-        guint   locked_down : 1;
-        guint   disable_command_line : 1;
-        guint   disable_lock_screen : 1;
-        guint   disable_log_out : 1;
-        guint   disable_force_quit : 1;
+#include "panel-lockdown.h"
 
-        GSList *disabled_applets;
+static PanelLockdown *shared_lockdown = NULL;
 
-        guint   listeners [N_LISTENERS];
+struct _PanelLockdownPrivate {
+        GSettings *desktop_settings;
+        GSettings *panel_settings;
 
-        GSList *closures;
-} PanelLockdown;
+        /* desktop-wide */
+        gboolean   disable_command_line;
+        gboolean   disable_lock_screen;
+        gboolean   disable_log_out;
 
-static PanelLockdown panel_lockdown = { 0, };
+        /* panel-specific */
+        gboolean   panels_locked_down;
+        gboolean   disable_force_quit;
+        char     **disabled_applets;
+};
 
+enum {
+        PROP_0,
+        PROP_DISABLE_COMMAND_LINE,
+        PROP_DISABLE_LOCK_SCREEN,
+        PROP_DISABLE_LOG_OUT,
+        PROP_PANELS_LOCKED_DOWN,
+        PROP_DISABLE_FORCE_QUIT
+};
 
-static inline void
-panel_lockdown_invoke_closures (PanelLockdown *lockdown)
-{
-        GSList *l;
-
-        for (l = lockdown->closures; l; l = l->next)
-                g_closure_invoke (l->data, NULL, 0, NULL, NULL);
-}
+G_DEFINE_TYPE (PanelLockdown, panel_lockdown, G_TYPE_OBJECT);
 
 static void
-locked_down_notify (GConfClient   *client,
-                    guint          cnxn_id,
-                    GConfEntry    *entry,
-                    PanelLockdown *lockdown)
+_panel_lockdown_disabled_applets_changed (GSettings     *settings,
+                                          char          *key,
+                                          PanelLockdown *lockdown)
 {
-        if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-                return;
-
-        lockdown->locked_down = gconf_value_get_bool (entry->value);
-
-        panel_lockdown_invoke_closures (lockdown);
+        if (lockdown->priv->disabled_applets)
+                g_strfreev (lockdown->priv->disabled_applets);
+        lockdown->priv->disabled_applets = g_settings_get_strv (lockdown->priv->panel_settings,
+                                                                PANEL_LOCKDOWN_DISABLED_APPLETS_KEY);
 }
 
-static void
-disable_command_line_notify (GConfClient   *client,
-                             guint          cnxn_id,
-                             GConfEntry    *entry,
-                             PanelLockdown *lockdown)
+static GObject *
+panel_lockdown_constructor (GType                  type,
+                            guint                  n_construct_properties,
+                            GObjectConstructParam *construct_properties)
 {
-        if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-                return;
-
-        lockdown->disable_command_line = gconf_value_get_bool (entry->value);
-
-        panel_lockdown_invoke_closures (lockdown);
+        GObject       *obj;
+        PanelLockdown *lockdown;
+
+        obj = G_OBJECT_CLASS (panel_lockdown_parent_class)->constructor (type,
+                                                                         n_construct_properties,
+                                                                         construct_properties);
+
+        lockdown = PANEL_LOCKDOWN (obj);
+
+        lockdown->priv->desktop_settings = g_settings_new (PANEL_DESKTOP_LOCKDOWN_SCHEMA);
+        lockdown->priv->panel_settings = g_settings_new (PANEL_LOCKDOWN_SCHEMA);
+
+        g_settings_bind (lockdown->priv->desktop_settings,
+                         PANEL_DESKTOP_DISABLE_COMMAND_LINE_KEY,
+                         lockdown,
+                         "disable-command-line",
+                         G_SETTINGS_BIND_GET);
+
+        g_settings_bind (lockdown->priv->desktop_settings,
+                         PANEL_DESKTOP_DISABLE_LOCK_SCREEN_KEY,
+                         lockdown,
+                         "disable-lock-screen",
+                         G_SETTINGS_BIND_GET);
+
+        g_settings_bind (lockdown->priv->desktop_settings,
+                         PANEL_DESKTOP_DISABLE_LOG_OUT_KEY,
+                         lockdown,
+                         "disable-log-out",
+                         G_SETTINGS_BIND_GET);
+
+        g_settings_bind (lockdown->priv->panel_settings,
+                         PANEL_LOCKDOWN_COMPLETE_LOCKDOWN_KEY,
+                         lockdown,
+                         "panels-locked-down",
+                         G_SETTINGS_BIND_GET);
+
+        g_settings_bind (lockdown->priv->panel_settings,
+                         PANEL_LOCKDOWN_DISABLE_FORCE_QUIT_KEY,
+                         lockdown,
+                         "disable-force-quit",
+                         G_SETTINGS_BIND_GET);
+
+        g_signal_connect (lockdown->priv->panel_settings,
+                          "changed::"PANEL_LOCKDOWN_DISABLED_APPLETS_KEY,
+                          G_CALLBACK (_panel_lockdown_disabled_applets_changed),
+                          lockdown);
+
+        _panel_lockdown_disabled_applets_changed (lockdown->priv->panel_settings,
+                                                  PANEL_LOCKDOWN_DISABLED_APPLETS_KEY,
+                                                  lockdown);
+
+        return obj;
 }
 
 static void
-disable_lock_screen_notify (GConfClient   *client,
-                            guint          cnxn_id,
-                            GConfEntry    *entry,
-                            PanelLockdown *lockdown)
+_panel_lockdown_set_property_helper (PanelLockdown *lockdown,
+                                     gboolean      *field,
+                                     const GValue  *value,
+                                     const char    *property)
 {
-        if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-                return;
-
-        lockdown->disable_lock_screen = gconf_value_get_bool (entry->value);
-
-        panel_lockdown_invoke_closures (lockdown);
-}
+        gboolean new;
 
-static void
-disable_log_out_notify (GConfClient   *client,
-                        guint          cnxn_id,
-                        GConfEntry    *entry,
-                        PanelLockdown *lockdown)
-{
-        if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
+        new = g_value_get_boolean (value);
+        if (new == *field)
                 return;
 
-        lockdown->disable_log_out = gconf_value_get_bool (entry->value);
-
-        panel_lockdown_invoke_closures (lockdown);
+        *field = new;
+        g_object_notify (G_OBJECT (lockdown), property);
 }
 
 static void
-disable_force_quit_notify (GConfClient   *client,
-                           guint          cnxn_id,
-                           GConfEntry    *entry,
-                           PanelLockdown *lockdown)
+panel_lockdown_set_property (GObject      *object,
+                             guint         prop_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
 {
-        if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-                return;
-
-        lockdown->disable_force_quit = gconf_value_get_bool (entry->value);
-
-        panel_lockdown_invoke_closures (lockdown);
+        PanelLockdown *lockdown;
+
+        g_return_if_fail (PANEL_IS_LOCKDOWN (object));
+
+        lockdown = PANEL_LOCKDOWN (object);
+
+        switch (prop_id) {
+        case PROP_DISABLE_COMMAND_LINE:
+                _panel_lockdown_set_property_helper (lockdown,
+                                                     &lockdown->priv->disable_command_line,
+                                                     value,
+                                                     "disable-command-line");
+                break;
+        case PROP_DISABLE_LOCK_SCREEN:
+                _panel_lockdown_set_property_helper (lockdown,
+                                                     &lockdown->priv->disable_lock_screen,
+                                                     value,
+                                                     "disable-lock-screen");
+                break;
+        case PROP_DISABLE_LOG_OUT:
+                _panel_lockdown_set_property_helper (lockdown,
+                                                     &lockdown->priv->disable_log_out,
+                                                     value,
+                                                     "disable-log-out");
+                break;
+        case PROP_PANELS_LOCKED_DOWN:
+                _panel_lockdown_set_property_helper (lockdown,
+                                                     &lockdown->priv->panels_locked_down,
+                                                     value,
+                                                     "panels-locked-down");
+                break;
+        case PROP_DISABLE_FORCE_QUIT:
+                _panel_lockdown_set_property_helper (lockdown,
+                                                     &lockdown->priv->disable_force_quit,
+                                                     value,
+                                                     "disable-force-quit");
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
 }
 
 static void
-disabled_applets_notify (GConfClient   *client,
-                         guint          cnxn_id,
-                         GConfEntry    *entry,
-                         PanelLockdown *lockdown)
+panel_lockdown_get_property (GObject    *object,
+                             guint       prop_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
 {
-        GSList *l;
-
-        if (!entry->value || entry->value->type != GCONF_VALUE_LIST ||
-            gconf_value_get_list_type (entry->value) != GCONF_VALUE_STRING)
-                return;
-
-        for (l = lockdown->disabled_applets; l; l = l->next)
-                g_free (l->data);
-        g_slist_free (lockdown->disabled_applets);
-        lockdown->disabled_applets = NULL;
-
-        for (l = gconf_value_get_list (entry->value); l; l = l->next) {
-                const char *iid = gconf_value_get_string (l->data);
-
-                lockdown->disabled_applets =
-                        g_slist_prepend (lockdown->disabled_applets,
-                                         g_strdup (iid));
+        PanelLockdown *lockdown;
+
+        g_return_if_fail (PANEL_IS_LOCKDOWN (object));
+
+        lockdown = PANEL_LOCKDOWN (object);
+
+        switch (prop_id) {
+        case PROP_DISABLE_COMMAND_LINE:
+                g_value_set_boolean (value, lockdown->priv->disable_command_line);
+                break;
+        case PROP_DISABLE_LOCK_SCREEN:
+                g_value_set_boolean (value, lockdown->priv->disable_lock_screen);
+                break;
+        case PROP_DISABLE_LOG_OUT:
+                g_value_set_boolean (value, lockdown->priv->disable_log_out);
+                break;
+        case PROP_PANELS_LOCKED_DOWN:
+                g_value_set_boolean (value, lockdown->priv->panels_locked_down);
+                break;
+        case PROP_DISABLE_FORCE_QUIT:
+                g_value_set_boolean (value, lockdown->priv->disable_force_quit);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
         }
-
-        panel_lockdown_invoke_closures (lockdown);
 }
 
-static gboolean
-panel_lockdown_load_bool (PanelLockdown         *lockdown,
-                          GConfClient           *client,
-                          const char            *key,
-                          GConfClientNotifyFunc  notify_func,
-                          int                    listener)
+static void
+panel_lockdown_dispose (GObject *object)
 {
-        GError   *error = NULL;
-        gboolean  retval;
-
-        retval = gconf_client_get_bool (client, key, &error);
-        if (error) {
-                g_warning ("Error getting value of '%s': %s\n",
-                           key, error->message);
-                retval = FALSE;
-        }
+        PanelLockdown *lockdown;
 
-        lockdown->listeners [listener] =
-                gconf_client_notify_add (client,
-                                         key,
-                                         notify_func,
-                                         lockdown,
-                                         NULL, NULL);
+        lockdown = PANEL_LOCKDOWN (object);
 
-        return retval;
-}
+        if (lockdown->priv->desktop_settings)
+                g_object_unref (lockdown->priv->desktop_settings);
+        lockdown->priv->desktop_settings = NULL;
 
-static GSList *
-panel_lockdown_load_disabled_applets (PanelLockdown *lockdown,
-                                      GConfClient   *client,
-                                      int            listener)
-{
-        GSList *retval;
+        if (lockdown->priv->panel_settings)
+                g_object_unref (lockdown->priv->panel_settings);
+        lockdown->priv->panel_settings = NULL;
 
-        retval = gconf_client_get_list (client,
-                                        DISABLED_APPLETS_KEY,
-                                        GCONF_VALUE_STRING,
-                                        NULL);
+        if (lockdown->priv->disabled_applets)
+                g_strfreev (lockdown->priv->disabled_applets);
+        lockdown->priv->disabled_applets = NULL;
 
-        lockdown->listeners [listener] =
-                gconf_client_notify_add (client,
-                                         DISABLED_APPLETS_KEY,
-                                         (GConfClientNotifyFunc) disabled_applets_notify,
-                                         lockdown,
-                                         NULL, NULL);
-
-        return retval;
+        G_OBJECT_CLASS (panel_lockdown_parent_class)->dispose (object);
 }
 
-void
-panel_lockdown_init (void)
+static void
+panel_lockdown_init (PanelLockdown *lockdown)
 {
-        GConfClient *client;
-        int          i = 0;
-
-        client = panel_gconf_get_client ();
-
-        gconf_client_add_dir (client,
-                              DESKTOP_GNOME_LOCKDOWN_DIR,
-                              GCONF_CLIENT_PRELOAD_ONELEVEL,
-                              NULL);
-
-        gconf_client_add_dir (client,
-                              PANEL_GLOBAL_LOCKDOWN_DIR,
-                              GCONF_CLIENT_PRELOAD_ONELEVEL,
-                              NULL);
-
-        panel_lockdown.locked_down =
-                panel_lockdown_load_bool (&panel_lockdown,
-                                          client,
-                                          PANEL_GLOBAL_LOCKED_DOWN_KEY,
-                                          (GConfClientNotifyFunc) locked_down_notify,
-                                          i++);
-
-        panel_lockdown.disable_command_line =
-                panel_lockdown_load_bool (&panel_lockdown,
-                                          client,
-                                          DISABLE_COMMAND_LINE_KEY,
-                                          (GConfClientNotifyFunc) disable_command_line_notify,
-                                          i++);
-        
-        panel_lockdown.disable_lock_screen =
-                panel_lockdown_load_bool (&panel_lockdown,
-                                          client,
-                                          DISABLE_LOCK_SCREEN_KEY,
-                                          (GConfClientNotifyFunc) disable_lock_screen_notify,
-                                          i++);
-
-        panel_lockdown.disable_log_out =
-                panel_lockdown_load_bool (&panel_lockdown,
-                                          client,
-                                          DISABLE_LOG_OUT_KEY,
-                                          (GConfClientNotifyFunc) disable_log_out_notify,
-                                          i++);
-
-        panel_lockdown.disable_force_quit =
-                panel_lockdown_load_bool (&panel_lockdown,
-                                          client,
-                                          DISABLE_FORCE_QUIT_KEY,
-                                          (GConfClientNotifyFunc) disable_force_quit_notify,
-                                          i++);
-
-        panel_lockdown.disabled_applets =
-                panel_lockdown_load_disabled_applets (&panel_lockdown,
-                                                      client,
-                                                      i++);
-
-        g_assert (i == N_LISTENERS);
-
-        panel_lockdown.initialized = TRUE;
+        lockdown->priv = G_TYPE_INSTANCE_GET_PRIVATE (lockdown,
+                                                      PANEL_TYPE_LOCKDOWN,
+                                                      PanelLockdownPrivate);
 }
 
-void
-panel_lockdown_finalize (void)
+static void
+panel_lockdown_class_init (PanelLockdownClass *lockdown_class)
 {
-        GConfClient *client;
-        GSList      *l;
-        int          i;
-
-        g_assert (panel_lockdown.initialized != FALSE);
-
-        client = panel_gconf_get_client ();
-
-        for (l = panel_lockdown.disabled_applets; l; l = l->next)
-                g_free (l->data);
-        g_slist_free (panel_lockdown.disabled_applets);
-        panel_lockdown.disabled_applets = NULL;
-
-        for (i = 0; i < N_LISTENERS; i++) {
-                if (panel_lockdown.listeners [i])
-                        gconf_client_notify_remove (client,
-                                                    panel_lockdown.listeners [i]);
-                panel_lockdown.listeners [i] = 0;
-        }
-
-        gconf_client_remove_dir (client,
-                                 PANEL_GLOBAL_LOCKDOWN_DIR,
-                                 NULL);
-
-        gconf_client_remove_dir (client,
-                                 DESKTOP_GNOME_LOCKDOWN_DIR,
-                                 NULL);
-
-        for (l = panel_lockdown.closures; l; l = l->next)
-                g_closure_unref (l->data);
-        g_slist_free (panel_lockdown.closures);
-        panel_lockdown.closures = NULL;
-
-        panel_lockdown.initialized = FALSE;
+        GObjectClass *gobject_class;
+
+        gobject_class = G_OBJECT_CLASS (lockdown_class);
+
+        gobject_class->constructor  = panel_lockdown_constructor;
+        gobject_class->set_property = panel_lockdown_set_property;
+        gobject_class->get_property = panel_lockdown_get_property;
+        gobject_class->dispose      = panel_lockdown_dispose;
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_DISABLE_COMMAND_LINE,
+                g_param_spec_boolean (
+                        "disable-command-line",
+                        "Disable command line",
+                        "Whether command line is disabled or not",
+                        TRUE,
+                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_DISABLE_LOCK_SCREEN,
+                g_param_spec_boolean (
+                        "disable-lock-screen",
+                        "Disable lock screen",
+                        "Whether lock screen is disabled or not",
+                        TRUE,
+                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_DISABLE_LOG_OUT,
+                g_param_spec_boolean (
+                        "disable-log-out",
+                        "Disable log out",
+                        "Whether log out is disabled or not",
+                        TRUE,
+                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_PANELS_LOCKED_DOWN,
+                g_param_spec_boolean (
+                        "panels-locked-down",
+                        "Full locked down of panels",
+                        "Whether panels are fully locked down or not",
+                        TRUE,
+                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+        g_object_class_install_property (
+                gobject_class,
+                PROP_DISABLE_FORCE_QUIT,
+                g_param_spec_boolean (
+                        "disable-force-quit",
+                        "Disable force quit",
+                        "Whether force quit is disabled or not",
+                        TRUE,
+                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+        g_type_class_add_private (lockdown_class,
+                                  sizeof (PanelLockdownPrivate));
 }
 
 gboolean
-panel_lockdown_get_locked_down (void)
+panel_lockdown_is_applet_disabled (PanelLockdown *lockdown,
+                                   const char    *iid)
 {
-        g_assert (panel_lockdown.initialized != FALSE);
+        int i;
 
-        return panel_lockdown.locked_down;
-}
+        g_return_val_if_fail (PANEL_IS_LOCKDOWN (lockdown), TRUE);
 
-gboolean
-panel_lockdown_get_not_locked_down (void)
-{
-        g_assert (panel_lockdown.initialized != FALSE);
+        for (i = 0; lockdown->priv->disabled_applets[i] != NULL; i++)
+                if (g_strcmp0 (lockdown->priv->disabled_applets[i], iid) == 0)
+                        return TRUE;
 
-        return !panel_lockdown.locked_down;
+        return FALSE;
 }
 
 gboolean
-panel_lockdown_get_disable_command_line (void)
+panel_lockdown_get_disable_command_line (PanelLockdown *lockdown)
 {
-        g_assert (panel_lockdown.initialized != FALSE);
+        g_return_val_if_fail (PANEL_IS_LOCKDOWN (lockdown), TRUE);
 
-        return panel_lockdown.disable_command_line;
+        return lockdown->priv->disable_command_line;
 }
 
 gboolean
-panel_lockdown_get_disable_lock_screen (void)
+panel_lockdown_get_disable_lock_screen (PanelLockdown *lockdown)
 {
-        g_assert (panel_lockdown.initialized != FALSE);
+        g_return_val_if_fail (PANEL_IS_LOCKDOWN (lockdown), TRUE);
 
-        return panel_lockdown.disable_lock_screen;
+        return lockdown->priv->disable_lock_screen;
 }
 
 gboolean
-panel_lockdown_get_disable_log_out (void)
+panel_lockdown_get_disable_log_out (PanelLockdown *lockdown)
 {
-        g_assert (panel_lockdown.initialized != FALSE);
+        g_return_val_if_fail (PANEL_IS_LOCKDOWN (lockdown), TRUE);
 
-        return panel_lockdown.disable_log_out;
+        return lockdown->priv->disable_log_out;
 }
 
 gboolean
-panel_lockdown_get_disable_force_quit (void)
+panel_lockdown_get_panels_locked_down (PanelLockdown *lockdown)
 {
-        g_assert (panel_lockdown.initialized != FALSE);
+        g_return_val_if_fail (PANEL_IS_LOCKDOWN (lockdown), TRUE);
 
-        return panel_lockdown.disable_force_quit;
+        return lockdown->priv->panels_locked_down;
 }
 
 gboolean
-panel_lockdown_is_applet_disabled (const char *iid)
+panel_lockdown_get_disable_force_quit (PanelLockdown *lockdown)
 {
-        GSList *l;
-
-        g_assert (panel_lockdown.initialized != FALSE);
-
-        for (l = panel_lockdown.disabled_applets; l; l = l->next)
-                if (!strcmp (l->data, iid))
-                        return TRUE;
+        g_return_val_if_fail (PANEL_IS_LOCKDOWN (lockdown), TRUE);
 
-        return FALSE;
+        return lockdown->priv->disable_force_quit;
 }
 
-static GClosure *
-panel_lockdown_notify_find (GSList    *closures,
-                            GCallback  callback_func,
-                            gpointer   user_data)
+typedef struct {
+        PanelLockdown       *lockdown;
+        PanelLockdownNotify  callback;
+        gpointer             callback_data;
+        guint                handler_id;
+} PanelLockdownNotifyData;
+
+static void
+_panel_lockdown_notify_data_destroy (gpointer data)
 {
-        GSList *l;
+        PanelLockdownNotifyData *notify_data = data;
 
-        for (l = closures; l; l = l->next) {
-                GCClosure *cclosure = l->data;
-                GClosure  *closure  = l->data;
+        g_signal_handler_disconnect (notify_data->lockdown,
+                                     notify_data->handler_id);
 
-                if (closure->data == user_data &&
-                    cclosure->callback == callback_func)
-                        return closure;
-        }
-
-        return NULL;
+        g_slice_free (PanelLockdownNotifyData, notify_data);
 }
 
 static void
-marshal_user_data (GClosure     *closure,
-                   GValue       *return_value,
-                   guint         n_param_values,
-                   const GValue *param_values,
-                   gpointer      invocation_hint,
-                   gpointer      marshal_data)
+panel_lockdown_on_notify_notified (GObject    *gobject,
+                                   GParamSpec *pspec,
+                                   gpointer    user_data)
 {
-        GCClosure *cclosure = (GCClosure*) closure;
+        PanelLockdownNotifyData *notify_data = user_data;
 
-        g_return_if_fail (cclosure->callback != NULL);
-        g_return_if_fail (n_param_values == 0);
+        g_assert (notify_data->callback != NULL);
+        g_assert ((gpointer) notify_data->lockdown == (gpointer) gobject);
 
-        ((void (*) (gpointer *))cclosure->callback) (closure->data);
+        notify_data->callback (notify_data->lockdown,
+                               notify_data->callback_data);
 }
 
+/* An object can only call this once per property.
+ * User NULL property to notify for all lockdown changes. (except disabled_applets) */
 void
-panel_lockdown_notify_add (GCallback callback_func,
-                           gpointer  user_data)
+panel_lockdown_on_notify (PanelLockdown       *lockdown,
+                          const char          *property,
+                          GObject             *object_while_alive,
+                          PanelLockdownNotify  callback,
+                          gpointer             callback_data)
 {
-        GClosure *closure;
+        PanelLockdownNotifyData *notify_data;
+        char *key;
+        char *signal_name;
+
+        g_return_if_fail (PANEL_IS_LOCKDOWN (lockdown));
+        g_return_if_fail (G_IS_OBJECT (object_while_alive));
+        g_return_if_fail (callback != NULL);
+
+        notify_data = g_slice_new0 (PanelLockdownNotifyData);
+
+        notify_data->lockdown      = lockdown;
+        notify_data->callback      = callback;
+        notify_data->callback_data = callback_data;
+        notify_data->handler_id    = 0;
+
+        if (property)
+                key = g_strdup_printf ("panel-lockdown-%s", property);
+        else
+                key = g_strdup_printf ("panel-lockdown");
+        g_object_set_data_full (object_while_alive, key,
+                                notify_data,
+                                _panel_lockdown_notify_data_destroy);
+        g_free (key);
+
+        if (property)
+                signal_name = g_strdup_printf ("notify::%s", property);
+        else
+                signal_name = g_strdup_printf ("notify");
+        notify_data->handler_id = g_signal_connect (lockdown, signal_name,
+                                                    G_CALLBACK (panel_lockdown_on_notify_notified),
+                                                    notify_data);
+        g_free (signal_name);
+}
 
-        g_assert (panel_lockdown_notify_find (panel_lockdown.closures,
-                                              callback_func,
-                                              user_data) == NULL);
+PanelLockdown *
+panel_lockdown_get (void)
+{
+        if (shared_lockdown == NULL) {
+                shared_lockdown = g_object_new (PANEL_TYPE_LOCKDOWN, NULL);
+                panel_cleanup_register (panel_cleanup_unref_and_nullify,
+                                        &shared_lockdown);
+        }
 
-        closure = g_cclosure_new (callback_func, user_data, NULL);
-        g_closure_set_marshal (closure, marshal_user_data);
+        return shared_lockdown;
+}
 
-        panel_lockdown.closures = g_slist_append (panel_lockdown.closures,
-                                                  closure);
+gboolean
+panel_lockdown_get_disable_command_line_s (void)
+{
+        return panel_lockdown_get_disable_command_line (panel_lockdown_get ());
 }
 
-void
-panel_lockdown_notify_remove (GCallback callback_func,
-                              gpointer  user_data)
+gboolean
+panel_lockdown_get_disable_lock_screen_s (void)
 {
-        GClosure *closure;
+        return panel_lockdown_get_disable_lock_screen (panel_lockdown_get ());
+}
 
-        closure = panel_lockdown_notify_find (panel_lockdown.closures,
-                                              callback_func,
-                                              user_data);
+gboolean
+panel_lockdown_get_disable_log_out_s (void)
+{
+        return panel_lockdown_get_disable_log_out (panel_lockdown_get ());
+}
 
-        g_assert (closure != NULL);
+gboolean
+panel_lockdown_get_panels_locked_down_s (void)
+{
+        return panel_lockdown_get_panels_locked_down (panel_lockdown_get ());
+}
 
-        panel_lockdown.closures = g_slist_remove (panel_lockdown.closures,
-                                                  closure);
+gboolean
+panel_lockdown_get_not_panels_locked_down_s (void)
+{
+        return !panel_lockdown_get_panels_locked_down (panel_lockdown_get ());
+}
 
-        g_closure_unref (closure);
+gboolean
+panel_lockdown_get_disable_force_quit_s (void)
+{
+        return panel_lockdown_get_disable_force_quit (panel_lockdown_get ());
 }
diff --git a/gnome-panel/panel-lockdown.h b/gnome-panel/panel-lockdown.h
index dbca5f1..67cd922 100644
--- a/gnome-panel/panel-lockdown.h
+++ b/gnome-panel/panel-lockdown.h
@@ -1,6 +1,8 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* vim: set sw=8 et: */
 /*
- * Copyright (C) 2004 Sun Microsystems, Inc.
+ * panel-lockdown.c: a lockdown tracker.
+ *
+ * Copyright (C) 2011 Novell, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -18,34 +20,66 @@
  * 02111-1307, USA.
  *
  * Authors:
- *      Matt Keenan  <matt keenan sun com>
- *      Mark McLoughlin  <mark skynet ie>
+ *      Vincent Untz <vuntz gnome org>
  */
 
 #ifndef __PANEL_LOCKDOWN_H__
 #define __PANEL_LOCKDOWN_H__
 
-#include <glib.h>
-#include <glib-object.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
-void panel_lockdown_init     (void);
-void panel_lockdown_finalize (void);
+#define PANEL_TYPE_LOCKDOWN            (panel_lockdown_get_type ())
+#define PANEL_LOCKDOWN(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_LOCKDOWN, PanelLockdown))
+#define PANEL_LOCKDOWN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), PANEL_TYPE_LOCKDOWN, PanelLockdownClass))
+#define PANEL_IS_LOCKDOWN(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PANEL_TYPE_LOCKDOWN))
+#define PANEL_IS_LOCKDOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_LOCKDOWN))
+#define PANEL_LOCKDOWN_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_LOCKDOWN, PanelLockdownClass))
+
+typedef struct _PanelLockdown          PanelLockdown;
+typedef struct _PanelLockdownClass     PanelLockdownClass;
+typedef struct _PanelLockdownPrivate   PanelLockdownPrivate;
+
+struct _PanelLockdown {
+        GObject parent;
+
+        /*< private > */
+        PanelLockdownPrivate *priv;
+};
+
+struct _PanelLockdownClass {
+        GObjectClass parent_class;
+};
+
+GType panel_lockdown_get_type (void);
+
+gboolean panel_lockdown_get_panels_locked_down   (PanelLockdown *lockdown);
+gboolean panel_lockdown_get_disable_command_line (PanelLockdown *lockdown);
+gboolean panel_lockdown_get_disable_lock_screen  (PanelLockdown *lockdown);
+gboolean panel_lockdown_get_disable_log_out      (PanelLockdown *lockdown);
+gboolean panel_lockdown_get_disable_force_quit   (PanelLockdown *lockdown);
+
+gboolean panel_lockdown_is_applet_disabled       (PanelLockdown *lockdown,
+                                                  const char *iid);
+
+typedef void (*PanelLockdownNotify) (PanelLockdown *lockdown,
+                                     gpointer       user_data);
 
-gboolean panel_lockdown_get_locked_down          (void);
-gboolean panel_lockdown_get_not_locked_down      (void);
-gboolean panel_lockdown_get_disable_command_line (void);
-gboolean panel_lockdown_get_disable_lock_screen  (void);
-gboolean panel_lockdown_get_disable_log_out      (void);
-gboolean panel_lockdown_get_disable_force_quit   (void);
+void     panel_lockdown_on_notify                (PanelLockdown *      lockdown,
+                                                  const char          *property,
+                                                  GObject             *object_while_alive,
+                                                  PanelLockdownNotify  callback,
+                                                  gpointer             callback_data);
 
-gboolean panel_lockdown_is_applet_disabled (const char *iid);
+PanelLockdown *panel_lockdown_get (void);
 
-void panel_lockdown_notify_add    (GCallback callback_func,
-                                   gpointer  user_data);
-void panel_lockdown_notify_remove (GCallback callback_func,
-                                   gpointer  user_data);
+gboolean panel_lockdown_get_panels_locked_down_s     (void);
+gboolean panel_lockdown_get_not_panels_locked_down_s (void);
+gboolean panel_lockdown_get_disable_command_line_s   (void);
+gboolean panel_lockdown_get_disable_lock_screen_s    (void);
+gboolean panel_lockdown_get_disable_log_out_s        (void);
+gboolean panel_lockdown_get_disable_force_quit_s     (void);
 
 G_END_DECLS
 
diff --git a/gnome-panel/panel-menu-bar.c b/gnome-panel/panel-menu-bar.c
index ef98f90..553a7be 100644
--- a/gnome-panel/panel-menu-bar.c
+++ b/gnome-panel/panel-menu-bar.c
@@ -407,7 +407,7 @@ panel_menu_bar_load (PanelWidget *panel,
 					   "edit",
 					   NULL,
 					   _("_Edit Menus"),
-					   panel_lockdown_get_not_locked_down);
+					   panel_lockdown_get_not_panels_locked_down_s);
 	}
 
 	panel_applet_add_callback (menubar->priv->info,
diff --git a/gnome-panel/panel-menu-button.c b/gnome-panel/panel-menu-button.c
index 8686ced..da9616b 100644
--- a/gnome-panel/panel-menu-button.c
+++ b/gnome-panel/panel-menu-button.c
@@ -100,7 +100,6 @@ struct _PanelMenuButtonPrivate {
 };
 
 static void panel_menu_button_disconnect_from_gconf (PanelMenuButton *button);
-static void panel_menu_button_recreate_menu         (PanelMenuButton *button);
 static void panel_menu_button_set_icon              (PanelMenuButton *button);
 
 static AtkObject *panel_menu_button_get_accessible  (GtkWidget       *widget);
@@ -192,9 +191,6 @@ panel_menu_button_finalize (GObject *object)
 {
 	PanelMenuButton *button = PANEL_MENU_BUTTON (object);
 
-	panel_lockdown_notify_remove (G_CALLBACK (panel_menu_button_recreate_menu),
-				      button);
-
 	panel_menu_button_disconnect_from_gconf (button);
 
 	if (button->priv->menu) {
@@ -411,23 +407,6 @@ panel_menu_button_create_menu (PanelMenuButton *button)
 	return button->priv->menu;
 }
 
-static void
-panel_menu_button_recreate_menu (PanelMenuButton *button)
-{
-	if (button->priv->menu) {
-		if (gtk_widget_get_visible (button->priv->menu))
-			gtk_menu_shell_deactivate (GTK_MENU_SHELL (button->priv->menu));
-
-		g_signal_handlers_disconnect_by_func (button->priv->menu,
-						      G_CALLBACK (panel_menu_button_menu_deactivated),
-						      button);
-
-		gtk_widget_destroy (button->priv->menu);
-	}
-
-	button->priv->menu = NULL;
-}
-
 void
 panel_menu_button_popup_menu (PanelMenuButton *button,
 			      guint            n_button,
@@ -680,15 +659,12 @@ panel_menu_button_load (const char  *menu_path,
 	    panel_is_program_in_path ("gmenu-simple-editor"))
 		panel_applet_add_callback (info, "edit", NULL,
 					   _("_Edit Menus"),
-					   panel_lockdown_get_not_locked_down);
+					   panel_lockdown_get_not_panels_locked_down_s);
 
 	panel_widget_set_applet_expandable (panel, GTK_WIDGET (button), FALSE, TRUE);
 	panel_widget_set_applet_size_constrained (panel, GTK_WIDGET (button), TRUE);
 
 	panel_menu_button_connect_to_gconf (button);
-
-	panel_lockdown_notify_add (G_CALLBACK (panel_menu_button_recreate_menu),
-				   button);
 }
 
 static char *
diff --git a/gnome-panel/panel-menu-items.c b/gnome-panel/panel-menu-items.c
index 19d3ac6..e2a510d 100644
--- a/gnome-panel/panel-menu-items.c
+++ b/gnome-panel/panel-menu-items.c
@@ -97,7 +97,6 @@ struct _PanelDesktopMenuItemPrivate {
 	PanelWidget *panel;
 
 	guint        use_image : 1;
-	guint        append_lock_logout : 1;
 };
 
 static void
@@ -313,11 +312,12 @@ panel_menu_item_uri_new (const char *uri,
 static GtkWidget *
 panel_menu_items_create_action_item_full (PanelActionButtonType  action_type,
 					  const char            *label,
-					  const char            *tooltip)
+					  const char            *tooltip,
+					  gboolean               create_even_if_disabled)
 {
 	GtkWidget *item;
 
-	if (panel_action_get_is_disabled (action_type))
+	if (!create_even_if_disabled && panel_action_get_is_disabled (action_type))
 		return NULL;
 
 	item = gtk_image_menu_item_new ();
@@ -345,7 +345,7 @@ static GtkWidget *
 panel_menu_items_create_action_item (PanelActionButtonType action_type)
 {
 	return panel_menu_items_create_action_item_full (action_type,
-							 NULL, NULL);
+							 NULL, NULL, FALSE);
 }
 
 static void
@@ -1189,7 +1189,8 @@ panel_place_menu_item_mounts_changed (GVolumeMonitor *monitor,
 }
 
 static GtkWidget *
-panel_desktop_menu_item_create_menu (PanelDesktopMenuItem *desktop_item)
+panel_desktop_menu_item_create_menu (PanelDesktopMenuItem *desktop_item,
+				     gboolean append_lock_logout)
 {
 	GtkWidget *desktop_menu;
 	GtkWidget *item;
@@ -1206,27 +1207,13 @@ panel_desktop_menu_item_create_menu (PanelDesktopMenuItem *desktop_item)
 	if (item)
 		gtk_menu_shell_append (GTK_MENU_SHELL (desktop_menu), item);
 
-	if (desktop_item->priv->append_lock_logout)
+	if (append_lock_logout)
 		panel_menu_items_append_lock_logout (desktop_menu);
 
 	return desktop_menu;
 }
 
 static void
-panel_desktop_menu_item_recreate_menu (PanelDesktopMenuItem *desktop_item)
-{
-	if (desktop_item->priv->menu) {
-		gtk_widget_destroy (desktop_item->priv->menu);
-		desktop_item->priv->menu = panel_desktop_menu_item_create_menu (desktop_item);
-		gtk_menu_item_set_submenu (GTK_MENU_ITEM (desktop_item),
-					   desktop_item->priv->menu);
-		panel_applet_menu_set_recurse (GTK_MENU (desktop_item->priv->menu),
-					       "menu_panel",
-					       desktop_item->priv->panel);
-	}
-}
-
-static void
 panel_place_menu_item_finalize (GObject *object)
 {
 	PanelPlaceMenuItem *menuitem = (PanelPlaceMenuItem *) object;
@@ -1297,17 +1284,6 @@ panel_place_menu_item_finalize (GObject *object)
 }
 
 static void
-panel_desktop_menu_item_finalize (GObject *object)
-{
-	PanelDesktopMenuItem *menuitem = (PanelDesktopMenuItem *) object;
-
-	if (menuitem->priv->append_lock_logout)
-		panel_lockdown_notify_remove (G_CALLBACK (panel_desktop_menu_item_recreate_menu),
-					      menuitem);
-	G_OBJECT_CLASS (panel_desktop_menu_item_parent_class)->finalize (object);
-}
-
-static void
 panel_place_menu_item_init (PanelPlaceMenuItem *menuitem)
 {
 	GFile *bookmark;
@@ -1421,10 +1397,6 @@ panel_place_menu_item_class_init (PanelPlaceMenuItemClass *klass)
 static void
 panel_desktop_menu_item_class_init (PanelDesktopMenuItemClass *klass)
 {
-	GObjectClass *gobject_class = (GObjectClass   *) klass;
-
-	gobject_class->finalize  = panel_desktop_menu_item_finalize;
-
 	g_type_class_add_private (klass, sizeof (PanelDesktopMenuItemPrivate));
 }
 
@@ -1478,12 +1450,8 @@ panel_desktop_menu_item_new (gboolean use_image,
 
 	menuitem->priv->use_image = use_image;
 
-	menuitem->priv->append_lock_logout = append_lock_logout;
-	if (append_lock_logout)
-		panel_lockdown_notify_add (G_CALLBACK (panel_desktop_menu_item_recreate_menu),
-					   menuitem);
-
-	menuitem->priv->menu = panel_desktop_menu_item_create_menu (menuitem);
+	menuitem->priv->menu = panel_desktop_menu_item_create_menu (menuitem,
+								    append_lock_logout);
 	gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem),
 				   menuitem->priv->menu);
 
@@ -1516,10 +1484,22 @@ panel_desktop_menu_item_set_panel (GtkWidget   *item,
 				       "menu_panel", panel);
 }
 
+static void
+panel_menu_items_lock_logout_separator_notified (PanelLockdown *lockdown,
+						 gpointer       user_data)
+{
+	GtkWidget *separator = user_data;
+
+	if (!panel_lockdown_get_disable_lock_screen (lockdown) ||
+	    !panel_lockdown_get_disable_log_out (lockdown))
+		gtk_widget_show (separator);
+	else
+		gtk_widget_hide (separator);
+}
+
 void
 panel_menu_items_append_lock_logout (GtkWidget *menu)
 {
-	gboolean    separator_inserted;
 	GList      *children;
 	GList      *last;
 	GtkWidget  *item;
@@ -1527,30 +1507,34 @@ panel_menu_items_append_lock_logout (GtkWidget *menu)
 	char       *label;
 	char       *tooltip;
 
-	separator_inserted = FALSE;
 	children = gtk_container_get_children (GTK_CONTAINER (menu));
 	last = g_list_last (children);
-	if (last != NULL) {
-		separator_inserted = GTK_IS_SEPARATOR (GTK_WIDGET (last->data));
-	}
+	if (last != NULL &&
+	    GTK_IS_SEPARATOR (last->data))
+		item = GTK_WIDGET (last->data);
+	else
+		item = add_menu_separator (menu);
 	g_list_free (children);
 
-	if (panel_lock_screen_action_available ("lock")) {
-		item = panel_menu_items_create_action_item (PANEL_ACTION_LOCK);
-		if (item != NULL) {
-			if (!separator_inserted) {
-				add_menu_separator (menu);
-				separator_inserted = TRUE;
-			}
+	panel_lockdown_on_notify (panel_lockdown_get (),
+				  NULL,
+				  G_OBJECT (item),
+				  panel_menu_items_lock_logout_separator_notified,
+				  item);
+	panel_menu_items_lock_logout_separator_notified (panel_lockdown_get (),
+							 item);
 
-			gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-		}
+	item = panel_menu_items_create_action_item_full (PANEL_ACTION_LOCK,
+							 NULL, NULL, TRUE);
+	if (item != NULL) {
+		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+		g_object_bind_property (panel_lockdown_get (),
+					"disable-lock-screen",
+					item,
+					"visible",
+					G_BINDING_SYNC_CREATE|G_BINDING_INVERT_BOOLEAN);
 	}
 
-	if (panel_lockdown_get_disable_log_out ())
-		return;
-	/* Below this, we only have log out/shutdown items */
-
 	/* Translators: translate "1" (msgctxt: "panel:showusername") to anything
 	 * but "1" if "Log Out %s" doesn't make any sense in your
 	 * language (where %s is a username).
@@ -1580,25 +1564,28 @@ panel_menu_items_append_lock_logout (GtkWidget *menu)
 	}
 
 	item = panel_menu_items_create_action_item_full (PANEL_ACTION_LOGOUT,
-							 label, tooltip);
+							 label, tooltip, TRUE);
 	g_free (label);
 	g_free (tooltip);
 
 	if (item != NULL) {
-		if (!separator_inserted) {
-			add_menu_separator (menu);
-			separator_inserted = TRUE;
-		}
-
 		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+		g_object_bind_property (panel_lockdown_get (),
+					"disable-log-out",
+					item,
+					"visible",
+					G_BINDING_SYNC_CREATE|G_BINDING_INVERT_BOOLEAN);
 	}
 
-	item = panel_menu_items_create_action_item (PANEL_ACTION_SHUTDOWN);
+	item = panel_menu_items_create_action_item_full (PANEL_ACTION_SHUTDOWN,
+							 NULL, NULL, TRUE);
 	if (item != NULL) {
-		if (!separator_inserted)
-			add_menu_separator (menu);
-
 		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+		g_object_bind_property (panel_lockdown_get (),
+					"disable-log-out",
+					item,
+					"visible",
+					G_BINDING_SYNC_CREATE|G_BINDING_INVERT_BOOLEAN);
 	}
 }
 
diff --git a/gnome-panel/panel-profile.c b/gnome-panel/panel-profile.c
index 21de7a3..77b71ce 100644
--- a/gnome-panel/panel-profile.c
+++ b/gnome-panel/panel-profile.c
@@ -2418,7 +2418,7 @@ panel_profile_can_be_moved_freely (PanelToplevel *toplevel)
 	const char *key;
 	GConfClient *client;
 
-	if (panel_lockdown_get_locked_down () ||
+	if (panel_lockdown_get_panels_locked_down_s () ||
 	    !panel_profile_is_writable_toplevel_orientation (toplevel))
 		return FALSE;
 
diff --git a/gnome-panel/panel-run-dialog.c b/gnome-panel/panel-run-dialog.c
index cda6afb..81ee3fd 100644
--- a/gnome-panel/panel-run-dialog.c
+++ b/gnome-panel/panel-run-dialog.c
@@ -1984,7 +1984,7 @@ panel_run_dialog_present (GdkScreen *screen,
 	GtkBuilder *gui;
 	GError     *error;
 
-	if (panel_lockdown_get_disable_command_line ())
+	if (panel_lockdown_get_disable_command_line_s ())
 		return;
 
 	if (static_dialog) {
diff --git a/gnome-panel/panel-schemas.h b/gnome-panel/panel-schemas.h
index f9e7934..1ef4d20 100644
--- a/gnome-panel/panel-schemas.h
+++ b/gnome-panel/panel-schemas.h
@@ -5,6 +5,16 @@
 #define PANEL_GENERAL_CONFIRM_PANEL_REMOVAL_KEY "confirm-panel-removal"
 #define PANEL_GENERAL_ENABLE_TOOLTIPS_KEY       "enable-tooltips"
 
+#define PANEL_LOCKDOWN_SCHEMA                 "org.gnome.gnome-panel.lockdown"
+#define PANEL_LOCKDOWN_COMPLETE_LOCKDOWN_KEY  "locked-down"
+#define PANEL_LOCKDOWN_DISABLE_FORCE_QUIT_KEY "disable-force-quit"
+#define PANEL_LOCKDOWN_DISABLED_APPLETS_KEY   "disabled-applets"
+
+#define PANEL_DESKTOP_LOCKDOWN_SCHEMA          "org.gnome.desktop.lockdown"
+#define PANEL_DESKTOP_DISABLE_COMMAND_LINE_KEY "disable-command-line"
+#define PANEL_DESKTOP_DISABLE_LOCK_SCREEN_KEY  "disable-lock-screen"
+#define PANEL_DESKTOP_DISABLE_LOG_OUT_KEY      "disable-log-out"
+
 #define PANEL_RUN_SCHEMA                 "org.gnome.gnome-panel.run-dialog"
 #define PANEL_RUN_HISTORY_KEY            "history"
 #define PANEL_RUN_ENABLE_COMPLETION_KEY  "enable-autocompletion"
diff --git a/gnome-panel/panel-toplevel.c b/gnome-panel/panel-toplevel.c
index 980e1e9..7c24b41 100644
--- a/gnome-panel/panel-toplevel.c
+++ b/gnome-panel/panel-toplevel.c
@@ -424,7 +424,7 @@ panel_toplevel_begin_grab_op (PanelToplevel   *toplevel,
 	    toplevel->priv->grab_op != PANEL_GRAB_OP_NONE)
 		return;
 
-	if (panel_lockdown_get_locked_down ())
+	if (panel_lockdown_get_panels_locked_down_s ())
 		return;
 
 	/* If any of the position/orientation are not writable,
diff --git a/gnome-panel/panel-util.c b/gnome-panel/panel-util.c
index 24841fc..cd47b3a 100644
--- a/gnome-panel/panel-util.c
+++ b/gnome-panel/panel-util.c
@@ -381,7 +381,7 @@ panel_lock_screen_action_available (const char *action)
 	g_return_val_if_fail (action != NULL, FALSE);
 
 	if (strcmp (action, "prefs") != 0 &&
-	    panel_lockdown_get_disable_lock_screen ())
+	    panel_lockdown_get_disable_lock_screen_s ())
 		return FALSE;
 
 	command = panel_lock_screen_action_get_command (action);
@@ -407,7 +407,7 @@ panel_lock_screen_action (GdkScreen  *screen,
 	g_return_if_fail (action != NULL);
 
 	if (strcmp (action, "prefs") != 0 &&
-	    panel_lockdown_get_disable_lock_screen ())
+	    panel_lockdown_get_disable_lock_screen_s ())
 		return;
 
 	command = panel_lock_screen_action_get_command (action);
@@ -446,13 +446,6 @@ panel_lock_screen_action (GdkScreen  *screen,
 	g_object_unref (app_info);
 }
 
-void
-panel_lock_screen (GdkScreen *screen)
-{
-	panel_lock_screen_action (screen, "lock");
-}
-
-
 #define PANEL_LAUNCHER_PERSONAL_PATH "panel2.d/default/launchers"
 
 static char *
diff --git a/gnome-panel/panel-util.h b/gnome-panel/panel-util.h
index 55409aa..f1ca69d 100644
--- a/gnome-panel/panel-util.h
+++ b/gnome-panel/panel-util.h
@@ -20,7 +20,6 @@ gboolean	panel_is_program_in_path (const char *program);
 gboolean	panel_is_uri_writable	(const char *uri);
 gboolean	panel_uri_exists	(const char *uri);
 
-void            panel_lock_screen                  (GdkScreen    *screen);
 void            panel_lock_screen_action           (GdkScreen    *screen,
                                                     const char   *action);
 gboolean        panel_lock_screen_action_available (const char   *action);
diff --git a/gnome-panel/panel-widget.c b/gnome-panel/panel-widget.c
index d6327ff..99d8760 100644
--- a/gnome-panel/panel-widget.c
+++ b/gnome-panel/panel-widget.c
@@ -1828,7 +1828,8 @@ panel_widget_applet_move_to_cursor (PanelWidget *panel)
 	applet = ad->applet;
 	g_assert(GTK_IS_WIDGET(applet));
 
-	if(!panel_widget_is_cursor(panel,10)) {
+	if(!panel_widget_is_cursor(panel,10) &&
+	   !panel_lockdown_get_panels_locked_down_s ()) {
 		GSList *list;
 
 		for(list=panels;
@@ -1840,8 +1841,7 @@ panel_widget_applet_move_to_cursor (PanelWidget *panel)
 			if (panel != new_panel &&
 			    panel_widget_is_cursor (new_panel,10) &&
 			    panel_screen_from_panel_widget (panel) ==
-			    panel_screen_from_panel_widget (new_panel) &&
-			    !panel_lockdown_get_locked_down ()) {
+			    panel_screen_from_panel_widget (new_panel)) {
 				pos = panel_widget_get_moveby (new_panel, 0, ad->drag_off);
 
 				if (pos < 0) pos = 0;
@@ -1980,7 +1980,8 @@ panel_widget_applet_button_press_event (GtkWidget      *widget,
 	/* Begin drag if the middle mouse button and modifier are pressed,
 	 * unless the panel is locked down or a grab is active (meaning a menu
 	 * is open) */
-	if (panel_lockdown_get_locked_down () || event->button != 2 ||
+	if (panel_lockdown_get_panels_locked_down_s () ||
+	    event->button != 2 ||
 	    modifiers != panel_bindings_get_mouse_button_modifier_keymask () ||
 	    gtk_grab_get_current() != NULL)
 		return FALSE;
@@ -2511,6 +2512,9 @@ panel_widget_tab_move (PanelWidget *panel,
 	AppletData  *ad;
 	GSList      *l;
 
+	if (panel_lockdown_get_panels_locked_down_s ())
+		return;
+
 	ad = panel->currently_dragged_applet;
 
 	if (!ad)
@@ -2545,8 +2549,7 @@ panel_widget_tab_move (PanelWidget *panel,
 		new_panel = previous_panel;
 	
 	if (new_panel &&
-	    (new_panel != panel) &&
-	    !panel_lockdown_get_locked_down ())
+	    (new_panel != panel))
 		panel_widget_reparent (panel, new_panel, ad->applet, 0);
 }
 
diff --git a/gnome-panel/panel.c b/gnome-panel/panel.c
index aa9c9bd..45b95b7 100644
--- a/gnome-panel/panel.c
+++ b/gnome-panel/panel.c
@@ -221,27 +221,9 @@ context_menu_show (GtkWidget *w,
 }
 
 static void
-panel_recreate_context_menu (PanelData *pd)
-{
-	if (pd->menu) {
-		if (gtk_widget_get_visible (pd->menu))
-			gtk_menu_shell_deactivate (GTK_MENU_SHELL (pd->menu));
-
-		g_signal_handlers_disconnect_by_func (pd->menu,
-						      context_menu_deactivate,
-						      pd);
-		g_object_unref (pd->menu);
-	}
-	pd->menu = NULL;
-}
-
-static void
 panel_destroy (PanelToplevel *toplevel,
 	       PanelData     *pd)
 {
-	panel_lockdown_notify_remove (G_CALLBACK (panel_recreate_context_menu),
-				      pd);
-
 	if (pd->menu) {
 		g_signal_handlers_disconnect_by_func (pd->menu,
 						      context_menu_deactivate,
@@ -274,6 +256,25 @@ panel_applet_move(PanelWidget *panel, GtkWidget *widget, gpointer data)
 	panel_applet_save_position (info, info->id, FALSE);
 }
 
+static void
+panel_menu_lockdown_changed (PanelLockdown *lockdown,
+			     gpointer       user_data)
+{
+	PanelData *pd = user_data;
+
+	if (pd->menu) {
+		if (gtk_widget_get_visible (pd->menu))
+			gtk_menu_shell_deactivate (GTK_MENU_SHELL (pd->menu));
+
+		g_signal_handlers_disconnect_by_func (pd->menu,
+						      context_menu_deactivate,
+						      pd);
+
+		g_object_unref (pd->menu);
+		pd->menu = NULL;
+	}
+}
+
 static GtkWidget *
 panel_menu_get (PanelWidget *panel, PanelData *pd)
 {
@@ -286,6 +287,12 @@ panel_menu_get (PanelWidget *panel, PanelData *pd)
 					  pd);
 			g_signal_connect (pd->menu, "show",
 					  G_CALLBACK (context_menu_show), pd);
+
+			panel_lockdown_on_notify (panel_lockdown_get (),
+						  NULL,
+						  G_OBJECT (pd->menu),
+						  panel_menu_lockdown_changed,
+						  pd);
 		}
 	}
 
@@ -979,7 +986,7 @@ panel_check_drop_forbidden (PanelWidget    *panel,
 	if (!panel)
 		return FALSE;
 
-	if (panel_lockdown_get_locked_down ())
+	if (panel_lockdown_get_panels_locked_down_s ())
 		return FALSE;
 
 	if (info == TARGET_ICON_INTERNAL ||
@@ -1074,7 +1081,7 @@ panel_receive_dnd_data (PanelWidget      *panel,
 	const guchar *data;
 	gboolean      success = FALSE;
 
-	if (panel_lockdown_get_locked_down ()) {
+	if (panel_lockdown_get_panels_locked_down_s ()) {
 		gtk_drag_finish (context, FALSE, FALSE, time_);
 		return;
 	}
@@ -1215,9 +1222,6 @@ panel_setup (PanelToplevel *toplevel)
 	
 	g_object_set_data (G_OBJECT (toplevel), "PanelData", pd);
 
-	panel_lockdown_notify_add (G_CALLBACK (panel_recreate_context_menu),
-				   pd);
-
 	panel_widget_setup (panel_widget);
 
 	g_signal_connect (toplevel, "drag_data_received",



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]