diff --git a/ChangeLog b/ChangeLog index dc3cf82..24eef9e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,58 @@ +2008-12-08 Jens Granseuer + + * plugins/xrandr/gsd-xrandr-manager.c: (error_message): make libnotify + optional again (bug #563226) + (handle_fn_f7): fix memory leak, use g_debug instead of g_print + +2008-12-02 Federico Mena Quintero + + Use a DBus interface to tell the XRANDR manager to apply the + stored configuration, instead of an X client message, so that we + can pass errors back to the caller. + + * plugins/xrandr/gsd-xrandr-manager.xml: Trivial DBus interface to + tell the XRANDR manager to apply the stored configuration. + + * plugins/xrandr/gsd-xrandr-manager.c + (gsd_xrandr_manager_apply_configuration): Moved from + on_client_message(). Now we are a DBus-Glib method, so that we + can pass back errors to the remote caller. + + * plugins/xrandr/Makefile.am: Add the machinery to generate DBus + glue. + +2008-12-02 Federico Mena Quintero + + * plugins/xrandr/gsd-xrandr-manager.c (error_message): Renamed + from error_dialog(); use libnotify instead of ugly dialogs for + error messages. + (gsd_xrandr_manager_start): Proxy the error from + gnome_rr_screen_new() to our caller. + (gsd_xrandr_manager_start): Display an error if we cannot apply + the initially-loaded configuration. + (generate_fn_f7_configs, get_allowed_rotations_for_output): Pass + GError arguments to the gnome_rr_*() functions. + (handle_fn_f7): Display an error if we cannot refresh the screen + configuration or apply the new one. + (output_rotation_item_activate_cb): Display an error if the + rotation cannot be applied. + +Tue Dec 2 15:37:21 2008 Søren Sandmann + + * plugins/xrandr/gsd-xrandr-manager.c: Add support for fn-F7 type + keys. + +2008-10-04 Jens Granseuer + + Merged from trunk. + + Patch by: Eric Piel + + * plugins/xrandr/gsd-xrandr-manager.c: + (output_rotation_item_activate_cb): ignore the "activate" signal for + deselected items so that the rotation setting doesn't reset when the + systray menu is opened (bug #554951) + ==================== 2.24.0 ==================== 2008-09-23 Rodrigo Moya diff --git a/plugins/xrandr/Makefile.am b/plugins/xrandr/Makefile.am index 54eda77..78637e6 100644 --- a/plugins/xrandr/Makefile.am +++ b/plugins/xrandr/Makefile.am @@ -1,6 +1,9 @@ icondir = $(datadir)/icons/hicolor context = apps +BUILT_SOURCES = \ + gsd-xrandr-manager-glue.h + ICON_FILES = \ gsd-xrandr-16.png \ gsd-xrandr-22.png \ @@ -30,35 +33,43 @@ uninstall-local: plugin_LTLIBRARIES = \ libxrandr.la +gsd-xrandr-manager-glue.h: gsd-xrandr-manager.xml Makefile + dbus-binding-tool --prefix=gsd_xrandr_manager --mode=glib-server $< > xgen-$(@F) \ + && ( cmp -s xgen-$(@F) $@ || cp xgen-$(@F) $@ ) \ + && rm -f xgen-$(@F) + libxrandr_la_SOURCES = \ + $(BUILT_SOURCES) \ gsd-xrandr-plugin.h \ gsd-xrandr-plugin.c \ gsd-xrandr-manager.h \ gsd-xrandr-manager.c -libxrandr_la_CPPFLAGS = \ - -I$(top_srcdir)/gnome-settings-daemon \ - -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ +libxrandr_la_CPPFLAGS = \ + -I$(top_srcdir)/gnome-settings-daemon \ + -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ $(AM_CPPFLAGS) -libxrandr_la_CFLAGS = \ +libxrandr_la_CFLAGS = \ $(SETTINGS_PLUGIN_CFLAGS) \ + $(LIBNOTIFY_CFLAGS) \ $(AM_CFLAGS) -libxrandr_la_LDFLAGS = \ +libxrandr_la_LDFLAGS = \ $(GSD_PLUGIN_LDFLAGS) -libxrandr_la_LIBADD = \ - $(SETTINGS_PLUGIN_LIBS) \ +libxrandr_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(LIBNOTIFY_LIBS) \ $(RANDR_LIBS) -plugin_in_files = \ +plugin_in_files = \ xrandr.gnome-settings-plugin.in plugin_DATA = $(plugin_in_files:.gnome-settings-plugin.in=.gnome-settings-plugin) -EXTRA_DIST = $(plugin_in_files) $(ICON_FILES) -CLEANFILES = $(plugin_DATA) +EXTRA_DIST = $(plugin_in_files) $(ICON_FILES) gsd-xrandr-manager.xml +CLEANFILES = $(plugin_DATA) $(BUILT_SOURCES) DISTCLEANFILES = $(plugin_DATA) @GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c index 4d8ce2f..ecac754 100644 --- a/plugins/xrandr/gsd-xrandr-manager.c +++ b/plugins/xrandr/gsd-xrandr-manager.c @@ -37,6 +37,7 @@ #include #include #include +#include #define GNOME_DESKTOP_USE_UNSTABLE_API @@ -48,6 +49,10 @@ #include #endif +#ifdef HAVE_LIBNOTIFY +#include +#endif + #include "gnome-settings-profile.h" #include "gsd-xrandr-manager.h" @@ -68,13 +73,19 @@ /* executable of the control center's display configuration capplet */ #define GSD_XRANDR_DISPLAY_CAPPLET "gnome-display-properties" +#define GSD_DBUS_PATH "/org/gnome/SettingsDaemon" +#define GSD_DBUS_NAME "org.gnome.SettingsDaemon" +#define GSD_XRANDR_DBUS_PATH GSD_DBUS_PATH "/XRANDR" +#define GSD_XRANDR_DBUS_NAME GSD_DBUS_NAME ".XRANDR" + struct GsdXrandrManagerPrivate { + DBusGConnection *dbus_connection; + /* Key code of the fn-F7 video key (XF86Display) */ guint keycode; GnomeRRScreen *rw_screen; gboolean running; - gboolean client_filter_set; GtkStatusIcon *status_icon; GtkWidget *popup_menu; @@ -82,6 +93,10 @@ struct GsdXrandrManagerPrivate GnomeRRLabeler *labeler; GConfClient *client; int notify_id; + + /* fn-F7 status */ + int current_fn_f7_config; /* -1 if no configs */ + GnomeRRConfig **fn_f7_configs; /* NULL terminated, NULL if there are no configs */ }; static void gsd_xrandr_manager_class_init (GsdXrandrManagerClass *klass); @@ -93,38 +108,472 @@ G_DEFINE_TYPE (GsdXrandrManager, gsd_xrandr_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; -static GdkAtom -gnome_randr_atom (void) +/* DBus method; see gsd-xrandr-manager.xml for the interface definition */ +static gboolean +gsd_xrandr_manager_apply_configuration (GsdXrandrManager *manager, + GError **error) { - return gdk_atom_intern ("_GNOME_RANDR_ATOM", FALSE); + GnomeRRScreen *screen = manager->priv->rw_screen; + + return gnome_rr_config_apply_stored (screen, error); } +/* We include this after the definition of gsd_xrandr_manager_apply_configuration() so the prototype will already exist */ +#include "gsd-xrandr-manager-glue.h" -static Atom -gnome_randr_xatom (void) +static gboolean +is_laptop (GnomeOutputInfo *output) { - return gdk_x11_atom_to_xatom (gnome_randr_atom()); + const char *output_name = output->name; + + if (output->connected && output_name && + (strstr ("lvds", output_name) || + strstr ("LVDS", output_name) || + strstr ("Lvds", output_name))) + { + return TRUE; + } + + return FALSE; } -static GdkFilterReturn -on_client_message (GdkXEvent *xevent, - GdkEvent *event, - gpointer data) +static gboolean +get_clone_size (GnomeRRScreen *screen, int *width, int *height) { - GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data); - GnomeRRScreen *screen = manager->priv->rw_screen; - XEvent *ev = (XEvent *)xevent; + GnomeRRMode **modes = gnome_rr_screen_list_clone_modes (screen); + int best_w, best_h; + int i; + + best_w = 0; + best_h = 0; - if (manager->priv->running && - ev->type == ClientMessage && - ev->xclient.message_type == gnome_randr_xatom ()) { + for (i = 0; modes[i] != NULL; ++i) { + GnomeRRMode *mode = modes[i]; + int w, h; - gnome_rr_config_apply_stored (screen); + w = gnome_rr_mode_get_width (mode); + h = gnome_rr_mode_get_height (mode); - return GDK_FILTER_REMOVE; + if (w * h > best_w * best_h) { + best_w = w; + best_h = h; + } } - /* Pass the event on to GTK+ */ - return GDK_FILTER_CONTINUE; + if (best_w > 0 && best_h > 0) { + if (width) + *width = best_w; + if (height) + *height = best_h; + + return TRUE; + } + + return FALSE; +} + +static void +print_output (GnomeOutputInfo *info) +{ + g_print (" Output: %s attached to %s\n", info->display_name, info->name); + g_print (" status: %s\n", info->on ? "on" : "off"); + g_print (" width: %d\n", info->width); + g_print (" height: %d\n", info->height); + g_print (" rate: %d\n", info->rate); + g_print (" position: %d %d\n", info->x, info->y); +} + +static void +print_configuration (GnomeRRConfig *config, const char *header) +{ + int i; + + g_print ("=== %s Configuration ===\n", header); + if (!config) { + g_print (" none\n"); + return; + } + + for (i = 0; config->outputs[i] != NULL; ++i) + print_output (config->outputs[i]); +} + +static GnomeRRConfig * +make_clone_setup (GnomeRRScreen *screen) +{ + GnomeRRConfig *result; + int width, height; + int i; + + if (!get_clone_size (screen, &width, &height)) + return NULL; + + result = gnome_rr_config_new_current (screen); + + for (i = 0; result->outputs[i] != NULL; ++i) { + GnomeOutputInfo *info = result->outputs[i]; + + info->on = FALSE; + if (info->connected) { + GnomeRROutput *output = + gnome_rr_screen_get_output_by_name (screen, info->name); + GnomeRRMode **modes = gnome_rr_output_list_modes (output); + int j; + int best_rate = 0; + + for (j = 0; modes[j] != NULL; ++j) { + GnomeRRMode *mode = modes[j]; + int w, h; + + w = gnome_rr_mode_get_width (mode); + h = gnome_rr_mode_get_height (mode); + + if (w == width && h == height) { + int r = gnome_rr_mode_get_freq (mode); + if (r > best_rate) + best_rate = r; + } + } + + if (best_rate > 0) { + info->on = TRUE; + info->width = width; + info->height = height; + info->rate = best_rate; + info->rotation = GNOME_RR_ROTATION_0; + info->x = 0; + info->y = 0; + } + } + } + + print_configuration (result, "clone setup"); + + return result; +} + +static gboolean +turn_on (GnomeRRScreen *screen, + GnomeOutputInfo *info, + int x, int y) +{ + GnomeRROutput *output = + gnome_rr_screen_get_output_by_name (screen, info->name); + GnomeRRMode *mode = gnome_rr_output_get_preferred_mode (output); + + if (mode) { + info->on = TRUE; + info->x = x; + info->y = y; + info->width = gnome_rr_mode_get_width (mode); + info->height = gnome_rr_mode_get_height (mode); + info->rotation = GNOME_RR_ROTATION_0; + info->rate = gnome_rr_mode_get_freq (mode); + + return TRUE; + } + + return FALSE; +} + +static GnomeRRConfig * +make_laptop_setup (GnomeRRScreen *screen) +{ + /* Turn on the laptop, disable everything else */ + GnomeRRConfig *result = gnome_rr_config_new_current (screen); + int i; + + for (i = 0; result->outputs[i] != NULL; ++i) { + GnomeOutputInfo *info = result->outputs[i]; + + if (is_laptop (info)) { + if (!info->on) { + if (!turn_on (screen, info, 0, 0)) { + gnome_rr_config_free (result); + result = NULL; + break; + } + } + } + else { + info->on = FALSE; + } + } + + print_configuration (result, "Laptop setup"); + + /* FIXME - Maybe we should return NULL if there is more than + * one connected "laptop" screen? + */ + return result; + +} + +static GnomeRRConfig * +make_xinerama_setup (GnomeRRScreen *screen) +{ + /* Turn on everything that has a preferred mode, and + * position it from left to right + */ + GnomeRRConfig *result = gnome_rr_config_new_current (screen); + int i; + int x; + + x = 0; + for (i = 0; result->outputs[i] != NULL; ++i) { + GnomeOutputInfo *info = result->outputs[i]; + + if (is_laptop (info)) { + if (info->on || turn_on (screen, info, x, 0)) { + x += info->width; + } + } + } + + for (i = 0; result->outputs[i] != NULL; ++i) { + GnomeOutputInfo *info = result->outputs[i]; + + if (info->connected && !is_laptop (info)) { + if (info->on || turn_on (screen, info, x, 0)) { + x += info->width; + } + } + } + + print_configuration (result, "xinerama setup"); + + return result; +} + +static GnomeRRConfig * +make_other_setup (GnomeRRScreen *screen) +{ + /* Turn off all laptops, and make all external monitors clone + * from (0, 0) + */ + + GnomeRRConfig *result = gnome_rr_config_new_current (screen); + int i; + + for (i = 0; result->outputs[i] != NULL; ++i) { + GnomeOutputInfo *info = result->outputs[i]; + + if (is_laptop (info)) { + info->on = FALSE; + } + else { + if (info->connected && !info->on) { + turn_on (screen, info, 0, 0); + } + } + } + + print_configuration (result, "other setup"); + + return result; +} + +static GPtrArray * +sanitize (GPtrArray *array) +{ + int i; + GPtrArray *new; + + g_print ("before sanitizing\n"); + + for (i = 0; i < array->len; ++i) { + if (array->pdata[i]) { + print_configuration (array->pdata[i], "before"); + } + } + + + /* Remove configurations that are duplicates of + * configurations earlier in the cycle + */ + for (i = 0; i < array->len; ++i) { + int j; + + for (j = 0; j < i; ++j) { + GnomeRRConfig *this = array->pdata[j]; + GnomeRRConfig *other = array->pdata[i]; + + if (this && other && gnome_rr_config_equal (this, other)) { + g_print ("removing duplicate configuration\n"); + gnome_rr_config_free (this); + array->pdata[j] = NULL; + break; + } + } + } + + for (i = 0; i < array->len; ++i) { + GnomeRRConfig *config = array->pdata[i]; + + if (config) { + gboolean all_off = TRUE; + int j; + + for (j = 0; config->outputs[j] != NULL; ++j) { + if (config->outputs[j]->on) + all_off = FALSE; + } + + if (all_off) { + gnome_rr_config_free (array->pdata[i]); + array->pdata[i] = NULL; + } + } + } + + /* Remove NULL configurations */ + new = g_ptr_array_new (); + + for (i = 0; i < array->len; ++i) { + if (array->pdata[i]) { + g_ptr_array_add (new, array->pdata[i]); + print_configuration (array->pdata[i], "Final"); + } + } + + g_ptr_array_add (new, NULL); + + g_ptr_array_free (array, TRUE); + + return new; +} + +static void +generate_fn_f7_configs (GsdXrandrManager *mgr) +{ + GPtrArray *array = g_ptr_array_new (); + GnomeRRScreen *screen = mgr->priv->rw_screen; + + g_print ("Generating configurations\n"); + + /* Free any existing list of configurations */ + if (mgr->priv->fn_f7_configs) { + int i; + + for (i = 0; mgr->priv->fn_f7_configs[i] != NULL; ++i) + gnome_rr_config_free (mgr->priv->fn_f7_configs[i]); + g_free (mgr->priv->fn_f7_configs); + + mgr->priv->fn_f7_configs = NULL; + mgr->priv->current_fn_f7_config = -1; + } + + g_ptr_array_add (array, gnome_rr_config_new_current (screen)); + g_ptr_array_add (array, make_xinerama_setup (screen)); + g_ptr_array_add (array, make_clone_setup (screen)); + g_ptr_array_add (array, make_laptop_setup (screen)); + g_ptr_array_add (array, make_other_setup (screen)); + g_ptr_array_add (array, gnome_rr_config_new_stored (screen, NULL)); /* NULL-GError - if this can't read the stored config, no big deal */ + g_ptr_array_add (array, NULL); + + array = sanitize (array); + + mgr->priv->fn_f7_configs = (GnomeRRConfig **)g_ptr_array_free (array, FALSE); + mgr->priv->current_fn_f7_config = 0; +} + +static void +error_message (GsdXrandrManager *mgr, const char *primary_text, GError *error_to_display, const char *secondary_text) +{ +#ifdef HAVE_LIBNOTIFY + GsdXrandrManagerPrivate *priv = mgr->priv; + NotifyNotification *notification; + + g_assert (error_to_display == NULL || secondary_text == NULL); + + notification = notify_notification_new_with_status_icon (primary_text, + error_to_display ? error_to_display->message : secondary_text, + GSD_XRANDR_ICON_NAME, + priv->status_icon); + notify_notification_show (notification, NULL); /* NULL-GError */ +#else + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + "%s", primary_text); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", + error_to_display ? error_to_display->message : secondary_text); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +#endif /* HAVE_LIBNOTIFY */ +} + +static void +handle_fn_f7 (GsdXrandrManager *mgr) +{ + GsdXrandrManagerPrivate *priv = mgr->priv; + GnomeRRScreen *screen = priv->rw_screen; + GnomeRRConfig *current; + GError *error; + + /* Theory of fn-F7 operation + * + * We maintain a datastructure "fn_f7_status", that contains + * a list of GnomeRRConfig's. Each of the GnomeRRConfigs has a + * mode (or "off") for each connected output. + * + * When the user hits fn-F7, we cycle to the next GnomeRRConfig + * in the data structure. If the data structure does not exist, it + * is generated. If the configs in the data structure do not match + * the current hardware reality, it is regenerated. + * + */ + g_debug ("Handling fn-f7"); + + error = NULL; + if (!gnome_rr_screen_refresh (screen, &error)) { + char *str; + + str = g_strdup_printf (_("Could not refresh the screen information: %s"), error->message); + g_error_free (error); + + error_message (mgr, str, NULL, _("Trying to switch the monitor configuration anyway.")); + g_free (str); + } + + if (!priv->fn_f7_configs) + generate_fn_f7_configs (mgr); + + current = gnome_rr_config_new_current (screen); + + if (priv->fn_f7_configs && + (!gnome_rr_config_match (current, priv->fn_f7_configs[0]) || + !gnome_rr_config_equal (current, priv->fn_f7_configs[mgr->priv->current_fn_f7_config]))) { + /* Our view of the world is incorrect, so regenerate the + * configurations + */ + generate_fn_f7_configs (mgr); + } + + gnome_rr_config_free (current); + + if (priv->fn_f7_configs) { + mgr->priv->current_fn_f7_config++; + + if (priv->fn_f7_configs[mgr->priv->current_fn_f7_config] == NULL) + mgr->priv->current_fn_f7_config = 0; + + g_debug ("cycling to next configuration (%d)", mgr->priv->current_fn_f7_config); + + print_configuration (priv->fn_f7_configs[mgr->priv->current_fn_f7_config], "new config"); + + g_debug ("applying"); + + error = NULL; + if (!gnome_rr_config_apply (priv->fn_f7_configs[mgr->priv->current_fn_f7_config], screen, &error)) { + error_message (mgr, _("Could not switch the monitor configuration"), error, NULL); + g_error_free (error); + } + } + else { + g_debug ("no configurations generated"); + } + g_debug ("done handling fn-f7"); } static GdkFilterReturn @@ -142,11 +591,8 @@ event_filter (GdkXEvent *xevent, if (xev->xany.type != KeyPress && xev->xany.type != KeyRelease) return GDK_FILTER_CONTINUE; - if (xev->xkey.keycode == manager->priv->keycode) { - /* FIXME: here we should cycle between valid - * configurations, and save them - */ - gnome_rr_config_apply_stored (manager->priv->rw_screen); + if (xev->xkey.keycode == manager->priv->keycode && xev->xany.type == KeyPress) { + handle_fn_f7 (manager); return GDK_FILTER_CONTINUE; } @@ -391,7 +837,7 @@ get_allowed_rotations_for_output (GsdXrandrManager *manager, GnomeOutputInfo *ou output->rotation = rotation_to_test; - if (gnome_rr_config_applicable (priv->configuration, priv->rw_screen)) { + if (gnome_rr_config_applicable (priv->configuration, priv->rw_screen, NULL)) { /* NULL-GError */ (*out_num_rotations)++; (*out_rotations) |= rotation_to_test; } @@ -424,20 +870,7 @@ add_unsupported_rotation_item (GsdXrandrManager *manager) } static void -error_dialog (const char *title, const char *msg) -{ - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - "%s", title); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", msg); - - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); -} - -static void -output_rotation_item_activate_cb (GtkMenuItem *item, gpointer data) +output_rotation_item_activate_cb (GtkCheckMenuItem *item, gpointer data) { GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data); struct GsdXrandrManagerPrivate *priv = manager->priv; @@ -445,25 +878,30 @@ output_rotation_item_activate_cb (GtkMenuItem *item, gpointer data) GnomeRRRotation rotation; GError *error; + /* Not interested in deselected items */ + if (!gtk_check_menu_item_get_active (item)) + return; + output = g_object_get_data (G_OBJECT (item), "output"); rotation = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "rotation")); output->rotation = rotation; error = NULL; - if (gnome_rr_config_save (priv->configuration, &error)) { - if (!gnome_rr_config_apply_stored (priv->rw_screen)) { - error_dialog (_("The selected rotation could not be applied"), - _("An error occurred while configuring the screen")); - /* FIXME: that message is really useless. Make - * gnome_rr_config_apply_stored() give us a meaningful - * error message! - */ - } - } else { - error_dialog (_("The selected rotation could not be applied"), - error->message); - g_error_free (error); + if (!gnome_rr_config_save (priv->configuration, &error)) { + error_message (manager, _("Could not save monitor configuration"), error, NULL); + if (error) + g_error_free (error); + + return; + } + + if (!gnome_rr_config_apply_stored (priv->rw_screen, &error)) { + error_message (manager, _("The selected rotation could not be applied"), error, NULL); + if (error) + g_error_free (error); + + return; } } @@ -687,15 +1125,15 @@ gboolean gsd_xrandr_manager_start (GsdXrandrManager *manager, GError **error) { + GError *my_error; + g_debug ("Starting xrandr manager"); manager->priv->rw_screen = gnome_rr_screen_new ( - gdk_screen_get_default (), on_randr_event, manager); + gdk_screen_get_default (), on_randr_event, manager, error); - if (manager->priv->rw_screen == NULL) { - g_set_error (error, 0, 0, "Failed to initialize XRandR extension"); + if (manager->priv->rw_screen == NULL) return FALSE; - } manager->priv->running = TRUE; manager->priv->client = gconf_client_get_default (); @@ -724,21 +1162,19 @@ gsd_xrandr_manager_start (GsdXrandrManager *manager, gdk_error_trap_pop (); } - gnome_rr_config_apply_stored (manager->priv->rw_screen); + my_error = NULL; + if (!gnome_rr_config_apply_stored (manager->priv->rw_screen, &my_error)) { + /* my_error can be null if there were no stored configurations */ + if (my_error) { + error_message (manager, _("Could not apply the stored configuration for monitors"), my_error, NULL); + g_error_free (my_error); + } + } gdk_window_add_filter (gdk_get_default_root_window(), (GdkFilterFunc)event_filter, manager); - if (!manager->priv->client_filter_set) { - /* FIXME: need to remove this in _stop; - * for now make sure to only add it once */ - gdk_add_client_message_filter (gnome_randr_atom (), - on_client_message, - manager); - manager->priv->client_filter_set = TRUE; - } - start_or_stop_icon (manager); return TRUE; @@ -781,6 +1217,11 @@ gsd_xrandr_manager_stop (GsdXrandrManager *manager) manager->priv->rw_screen = NULL; } + if (manager->priv->dbus_connection != NULL) { + dbus_g_connection_unref (manager->priv->dbus_connection); + manager->priv->dbus_connection = NULL; + } + status_icon_stop (manager); } @@ -856,6 +1297,8 @@ gsd_xrandr_manager_class_init (GsdXrandrManagerClass *klass) object_class->dispose = gsd_xrandr_manager_dispose; object_class->finalize = gsd_xrandr_manager_finalize; + dbus_g_object_type_install_info (GSD_TYPE_XRANDR_MANAGER, &dbus_glib_gsd_xrandr_manager_object_info); + g_type_class_add_private (klass, sizeof (GsdXrandrManagerPrivate)); } @@ -869,6 +1312,9 @@ gsd_xrandr_manager_init (GsdXrandrManager *manager) manager->priv = GSD_XRANDR_MANAGER_GET_PRIVATE (manager); manager->priv->keycode = keycode; + + manager->priv->current_fn_f7_config = -1; + manager->priv->fn_f7_configs = NULL; } static void @@ -886,6 +1332,26 @@ gsd_xrandr_manager_finalize (GObject *object) G_OBJECT_CLASS (gsd_xrandr_manager_parent_class)->finalize (object); } +static gboolean +register_manager_dbus (GsdXrandrManager *manager) +{ + GError *error = NULL; + + manager->priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (manager->priv->dbus_connection == NULL) { + if (error != NULL) { + g_warning ("Error getting session bus: %s", error->message); + g_error_free (error); + } + return FALSE; + } + + /* Hmm, should we do this in gsd_xrandr_manager_start()? */ + dbus_g_connection_register_g_object (manager->priv->dbus_connection, GSD_XRANDR_DBUS_PATH, G_OBJECT (manager)); + + return TRUE; +} + GsdXrandrManager * gsd_xrandr_manager_new (void) { @@ -895,6 +1361,11 @@ gsd_xrandr_manager_new (void) manager_object = g_object_new (GSD_TYPE_XRANDR_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); + + if (!register_manager_dbus (manager_object)) { + g_object_unref (manager_object); + return NULL; + } } return GSD_XRANDR_MANAGER (manager_object); diff --git a/plugins/xrandr/gsd-xrandr-manager.xml b/plugins/xrandr/gsd-xrandr-manager.xml new file mode 100644 index 0000000..2efd18b --- /dev/null +++ b/plugins/xrandr/gsd-xrandr-manager.xml @@ -0,0 +1,8 @@ + + + + + + + +