diff --git a/src/lockscreen-manager.c b/src/lockscreen-manager.c index 575db3eaac2d853fb0c0386435a1a9b2ee2ea4d6..1e0814e425580e4fe83b0ec6777e79262bb525ca 100644 --- a/src/lockscreen-manager.c +++ b/src/lockscreen-manager.c @@ -79,18 +79,18 @@ static void lockscreen_lock (PhoshLockscreenManager *self) { PhoshLockscreenManagerPrivate *priv = phosh_lockscreen_manager_get_instance_private (self); - PhoshMonitor *monitor; + PhoshMonitor *primary_monitor; PhoshWayland *wl = phosh_wayland_get_default (); PhoshShell *shell = phosh_shell_get_default (); PhoshMonitorManager *monitor_manager = phosh_shell_get_monitor_manager (shell); - monitor = phosh_shell_get_primary_monitor (shell); - g_return_if_fail (monitor); + primary_monitor = phosh_shell_get_primary_monitor (shell); + g_return_if_fail (primary_monitor); /* The primary output gets the clock, keypad, ... */ priv->lockscreen = PHOSH_LOCKSCREEN (phosh_lockscreen_new ( phosh_wayland_get_zwlr_layer_shell_v1(wl), - monitor->wl_output)); + primary_monitor->wl_output)); priv->input_inhibitor = zwlr_input_inhibit_manager_v1_get_inhibitor( @@ -98,9 +98,11 @@ lockscreen_lock (PhoshLockscreenManager *self) /* Lock all other outputs */ priv->shields = g_ptr_array_new_with_free_func ((GDestroyNotify) (gtk_widget_destroy)); - for (int i = 1; i < phosh_monitor_manager_get_num_monitors (monitor_manager); i++) { - monitor = phosh_monitor_manager_get_monitor (monitor_manager, i); - if (monitor == NULL) + + for (int i = 0; i < phosh_monitor_manager_get_num_monitors (monitor_manager); i++) { + PhoshMonitor *monitor = phosh_monitor_manager_get_monitor (monitor_manager, i); + + if (monitor == NULL || monitor == primary_monitor) continue; g_ptr_array_add (priv->shields, phosh_lockshield_new ( phosh_wayland_get_zwlr_layer_shell_v1 (wl), diff --git a/src/main.c b/src/main.c index bb983cf5e16bf8a9a4acdb350d74c35bb81fdef9..4def01918487796640272d392dea77b660d6fc79 100644 --- a/src/main.c +++ b/src/main.c @@ -53,7 +53,11 @@ int main(int argc, char *argv[]) opt_context = g_option_context_new ("- A phone graphical shell"); g_option_context_add_main_entries (opt_context, options, NULL); g_option_context_add_group (opt_context, gtk_get_option_group (TRUE)); - g_option_context_parse (opt_context, &argc, &argv, &err); + if (!g_option_context_parse (opt_context, &argc, &argv, &err)) { + g_warning ("%s", err->message); + g_clear_error (&err); + return 1; + } if (version) { print_version (); diff --git a/src/monitor-manager.c b/src/monitor-manager.c index 14ae8564ac34a8c45673c81c10185d34b0a4c812..9574a048078ec99db0b848b850a4c97c6174fc52 100644 --- a/src/monitor-manager.c +++ b/src/monitor-manager.c @@ -95,6 +95,7 @@ phosh_monitor_manager_handle_get_resources ( for (int i = 0; i < self->monitors->len; i++) { PhoshMonitor *monitor = g_ptr_array_index (self->monitors, i); GVariantBuilder crtcs, modes, clones, properties; + gboolean is_primary; if (!phosh_monitor_is_configured(monitor)) continue; @@ -114,6 +115,9 @@ phosh_monitor_manager_handle_get_resources ( g_variant_new_int32 (monitor->width_mm)); g_variant_builder_add (&properties, "{sv}", "height-mm", g_variant_new_int32 (monitor->height_mm)); + is_primary = (monitor == phosh_shell_get_primary_monitor (phosh_shell_get_default())); + g_variant_builder_add (&properties, "{sv}", "primary", + g_variant_new_boolean (is_primary)); g_variant_builder_add (&output_builder, "(uxiausauaua{sv})", i, /* ID */ @@ -464,6 +468,7 @@ phosh_monitor_manager_handle_get_current_state ( PhoshMonitor *monitor = g_ptr_array_index (self->monitors, i); GVariantBuilder logical_monitor_monitors_builder; g_autofree gchar *serial = NULL; + gboolean is_primary; if (!phosh_monitor_is_configured(monitor)) continue; @@ -479,6 +484,7 @@ phosh_monitor_manager_handle_get_current_state ( serial /* monitor_spec->serial, */ ); + is_primary = (monitor == phosh_shell_get_primary_monitor (phosh_shell_get_default())); g_variant_builder_add (&logical_monitors_builder, LOGICAL_MONITOR_FORMAT, monitor->x, /* logical_monitor->rect.x */ @@ -486,7 +492,7 @@ phosh_monitor_manager_handle_get_current_state ( /* (double) logical_monitor->scale */ (double)monitor->scale, 0, /* logical_monitor->transform */ - i == 0, /* logical_monitor->is_primary */ + is_primary, /* logical_monitor->is_primary */ &logical_monitor_monitors_builder, NULL); } @@ -510,8 +516,94 @@ phosh_monitor_manager_handle_get_current_state ( return TRUE; } +#undef LOGICAL_MONITORS_FORMAT +#undef LOGICAL_MONITOR_FORMAT +#undef LOGICAL_MONITOR_MONITORS_FORMAT +#undef MODES_FORMAT +#undef MODE_FORMAT +#undef MONITORS_FORMAT +#undef MONITOR_FORMAT +#define MONITOR_CONFIG_FORMAT "(ssa{sv})" +#define MONITOR_CONFIGS_FORMAT "a" MONITOR_CONFIG_FORMAT + + +/* TODO: This can later become get_monitor_config_from_variant */ +static PhoshMonitor * +find_monitor_from_variant(PhoshMonitorManager *self, + GVariant *monitor_config_variant, + GError **err) +{ + g_autofree char *connector = NULL; + g_autofree char *mode_id = NULL; + g_autoptr (GVariant) properties_variant = NULL; + PhoshMonitor *monitor; + + g_variant_get (monitor_config_variant, "(ss@a{sv})", + &connector, + &mode_id, + &properties_variant); + + /* Look for the monitor associated with this connector + TODO: We don't do any actual configuration yet. + */ + monitor = phosh_monitor_manager_find_monitor (self, connector); + if (monitor == NULL) { + g_set_error (err, G_IO_ERROR, G_IO_ERROR_FAILED, + "Could not find monitor for connector '%s'", connector); + } + return monitor; +} + +#define LOGICAL_MONITOR_CONFIG_FORMAT "(iidub" MONITOR_CONFIGS_FORMAT ")" + +/* TODO: this can later become get-logical_monitor_config_from_variant */ +static PhoshMonitor * +check_primary_monitor_from_variant (PhoshMonitorManager *self, + GVariant *logical_monitor_config_variant, + GError **err) +{ + int x, y; + unsigned int transform; + double scale; + gboolean is_primary; + GVariantIter *monitor_configs_iter; + PhoshMonitor *monitor = NULL; + + g_variant_get (logical_monitor_config_variant, LOGICAL_MONITOR_CONFIG_FORMAT, + &x, + &y, + &scale, + &transform, + &is_primary, + &monitor_configs_iter); + + if (!is_primary) + return NULL; + + while (TRUE) { + GVariant *monitor_config_variant = + g_variant_iter_next_value (monitor_configs_iter); + + if (!monitor_config_variant) + break; + + monitor = + find_monitor_from_variant (self, + monitor_config_variant, err); + g_variant_unref (monitor_config_variant); + + if (monitor == NULL) + break; + } + g_variant_iter_free (monitor_configs_iter); + return monitor; +} +#undef LOGICAL_MONITOR_CONFIG_FORMAT +#undef MONITOR_CONFIGS_FORMAT +#undef MONITOR_CONFIG_FORMAT + static gboolean phosh_monitor_manager_handle_apply_monitors_config ( PhoshDisplayDbusOrgGnomeMutterDisplayConfig *skeleton, @@ -521,9 +613,59 @@ phosh_monitor_manager_handle_apply_monitors_config ( GVariant *logical_monitor_configs_variant, GVariant *properties_variant) { - g_debug ("Stubbed DBus call %s", __func__); + PhoshMonitorManager *self = PHOSH_MONITOR_MANAGER (skeleton); + GVariantIter logical_monitor_configs_iter; + GError *err = NULL; + PhoshMonitor *primary_monitor = NULL; + PhoshShell *shell = phosh_shell_get_default(); + + g_debug ("Mostly Stubbed DBus call %s", __func__); + + if (serial != self->serial) { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "The requested configuration is based on stale information"); + return TRUE; + } + + g_variant_iter_init (&logical_monitor_configs_iter, + logical_monitor_configs_variant); + + while (TRUE) { + GVariant *logical_monitor_config_variant = + g_variant_iter_next_value (&logical_monitor_configs_iter); + + if (!logical_monitor_config_variant) + break; + + g_variant_unref (logical_monitor_config_variant); + + primary_monitor = + check_primary_monitor_from_variant (self, + logical_monitor_config_variant, + &err); + if (primary_monitor == NULL && err) { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "%s", err->message); + return TRUE; + } + + if (primary_monitor) + break; + } + + if (primary_monitor == NULL) { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "No primary monitor found"); + return TRUE; + } + if (primary_monitor != phosh_shell_get_primary_monitor (shell)) { + g_debug ("New primary monitor is %s", primary_monitor->name); + phosh_shell_set_primary_monitor (shell, primary_monitor); + } - /* Just do nothing for the moment */ phosh_display_dbus_org_gnome_mutter_display_config_complete_apply_monitors_config ( skeleton, invocation); @@ -644,14 +786,20 @@ phosh_monitor_manager_get_monitor (PhoshMonitorManager *self, guint num) } +PhoshMonitor * +phosh_monitor_manager_find_monitor (PhoshMonitorManager *self, const gchar *name) +{ + for (int i = 0; i < self->monitors->len; i++) { + PhoshMonitor *monitor = g_ptr_array_index (self->monitors, i); + if (!g_strcmp0 (monitor->name, name)) + return monitor; + } + return NULL; +} + + guint phosh_monitor_manager_get_num_monitors (PhoshMonitorManager *self) { return self->monitors->len; } - - -#undef MONITOR_MODE_SPEC_FORMAT -#undef MONITOR_CONFIG_FORMAT -#undef MONITOR_CONFIGS_FORMAT -#undef LOGICAL_MONITOR_CONFIG_FORMAT diff --git a/src/monitor-manager.h b/src/monitor-manager.h index 4ddf9e6a269b9a8503c766e4ed5b308c8f7ba764..3ca55ac8241d1c367395e9def5d39c768c4c591c 100644 --- a/src/monitor-manager.h +++ b/src/monitor-manager.h @@ -19,3 +19,5 @@ void phosh_monitor_manager_add_monitor (PhoshMoni PhoshMonitor * phosh_monitor_manager_get_monitor (PhoshMonitorManager *self, guint monitor); guint phosh_monitor_manager_get_num_monitors (PhoshMonitorManager *self); +PhoshMonitor * phosh_monitor_manager_find_monitor (PhoshMonitorManager *self, + const gchar *name); diff --git a/src/shell.c b/src/shell.c index 9b56a9856a7c6f48b6109cd19fe55f45784682cc..2ba589f1197da3e4ffcd251b52c472faee41e9d4 100644 --- a/src/shell.c +++ b/src/shell.c @@ -40,6 +40,7 @@ enum { PHOSH_SHELL_PROP_0, PHOSH_SHELL_PROP_ROTATION, PHOSH_SHELL_PROP_LOCKED, + PHOSH_SHELL_PROP_PRIMARY_MONITOR, PHOSH_SHELL_PROP_LAST_PROP }; static GParamSpec *props[PHOSH_SHELL_PROP_LAST_PROP]; @@ -61,6 +62,7 @@ typedef struct struct popup *favorites; struct popup *settings; + PhoshMonitor *primary_monitor; PhoshMonitorManager *monitor_manager; PhoshLockscreenManager *lockscreen_manager; } PhoshShellPrivate; @@ -348,6 +350,16 @@ panels_create (PhoshShell *self) } +static void +panels_dispose (PhoshShell *self) +{ + PhoshShellPrivate *priv = phosh_shell_get_instance_private (self); + + g_clear_pointer (&priv->panel, phosh_cp_widget_destroy); + g_clear_pointer (&priv->home, phosh_cp_widget_destroy); +} + + static void background_create (PhoshShell *self) { @@ -411,6 +423,9 @@ phosh_shell_set_property (GObject *object, case PHOSH_SHELL_PROP_LOCKED: phosh_shell_set_locked (self, g_value_get_boolean (value)); break; + case PHOSH_SHELL_PROP_PRIMARY_MONITOR: + phosh_shell_set_primary_monitor (self, g_value_get_object (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -435,6 +450,9 @@ phosh_shell_get_property (GObject *object, g_value_set_boolean (value, phosh_lockscreen_manager_get_locked (priv->lockscreen_manager)); break; + case PHOSH_SHELL_PROP_PRIMARY_MONITOR: + g_value_set_object (value, phosh_shell_get_primary_monitor (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -448,8 +466,8 @@ phosh_shell_dispose (GObject *object) PhoshShell *self = PHOSH_SHELL (object); PhoshShellPrivate *priv = phosh_shell_get_instance_private(self); + panels_dispose (self); g_clear_pointer (&priv->background, phosh_cp_widget_destroy); - g_clear_pointer (&priv->panel, phosh_cp_widget_destroy); g_clear_object (&priv->lockscreen_manager); g_clear_object (&priv->monitor_manager); phosh_system_prompter_unregister (); @@ -516,6 +534,13 @@ phosh_shell_class_init (PhoshShellClass *klass) FALSE, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); + props[PHOSH_SHELL_PROP_PRIMARY_MONITOR] = + g_param_spec_object ("primary-monitor", + "Primary monitor", + "The primary monitor", + PHOSH_TYPE_MONITOR, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (object_class, PHOSH_SHELL_PROP_LAST_PROP, props); } @@ -550,6 +575,32 @@ phosh_shell_rotate_display (PhoshShell *self, } +void +phosh_shell_set_primary_monitor (PhoshShell *self, PhoshMonitor *monitor) +{ + PhoshShellPrivate *priv; + PhoshMonitor *m = NULL; + + g_return_if_fail (monitor); + g_return_if_fail (PHOSH_IS_SHELL (self)); + priv = phosh_shell_get_instance_private (self); + + for (int i = 0; i < phosh_monitor_manager_get_num_monitors (priv->monitor_manager); i++) { + m = phosh_monitor_manager_get_monitor (priv->monitor_manager, i); + if (monitor == m) + break; + } + g_return_if_fail (monitor == m); + + priv->primary_monitor = monitor; + /* Move panels to the new monitor be recreating the layer shell surfaces */ + panels_dispose (self); + panels_create (self); + + g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_SHELL_PROP_PRIMARY_MONITOR]); +} + + PhoshMonitor * phosh_shell_get_primary_monitor (PhoshShell *self) { @@ -559,6 +610,10 @@ phosh_shell_get_primary_monitor (PhoshShell *self) g_return_val_if_fail (PHOSH_IS_SHELL (self), NULL); priv = phosh_shell_get_instance_private (self); + if (priv->primary_monitor) + return priv->primary_monitor; + + /* When the shell started up we might not have had all monitors */ monitor = phosh_monitor_manager_get_monitor (priv->monitor_manager, 0); g_return_val_if_fail (monitor, NULL); diff --git a/src/shell.h b/src/shell.h index cc0d7712e036966eca122b0556b86b44a7b674d6..f16b10f3f26bab7a00c14ad957dd3dd241f141bb 100644 --- a/src/shell.h +++ b/src/shell.h @@ -28,6 +28,7 @@ void phosh_shell_get_usable_area (PhoshShell *self, void phosh_shell_set_locked (PhoshShell *self, gboolean locked); void phosh_shell_lock (PhoshShell *self); void phosh_shell_unlock (PhoshShell *self); +void phosh_shell_set_primary_monitor (PhoshShell *self, PhoshMonitor *monitor); PhoshMonitor *phosh_shell_get_primary_monitor (PhoshShell *self); PhoshMonitorManager *phosh_shell_get_monitor_manager (PhoshShell *self); #endif /* PHOSH_H */ diff --git a/src/system-prompter.c b/src/system-prompter.c index f7c04e6d2f1dea44a1937afe35cc06796eb2a7ae..14482be59acec2c4572dbc1a4413738e4bc81b61 100644 --- a/src/system-prompter.c +++ b/src/system-prompter.c @@ -37,7 +37,7 @@ new_prompt_cb (GcrSystemPrompter *prompter, g_debug ("Building new system prompt"); g_return_val_if_fail (GCR_IS_SYSTEM_PROMPTER (prompter), NULL); return GCR_PROMPT (phosh_system_prompt_new (phosh_wayland_get_zwlr_layer_shell_v1 (wl), - phosh_shell_get_primary_monitor (shell))); + phosh_shell_get_primary_monitor (shell)->wl_output)); }