From 7bc2a00fea07365114eab97b15ca2ca38789efc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 5 Oct 2018 14:34:52 +0200 Subject: [PATCH 1/8] main: Handle command line parsing errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Guido Günther --- src/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index bb983cf5e..4def01918 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 (); -- GitLab From 26064e2e0b7289189f98b6c61b1ce5d8325714e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 5 Oct 2018 14:34:52 +0200 Subject: [PATCH 2/8] monitor-manager: undefine variant format strings right after usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This keeps them local to the functions using them. Signed-off-by: Guido Günther --- src/monitor-manager.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/monitor-manager.c b/src/monitor-manager.c index 14ae8564a..2debd1900 100644 --- a/src/monitor-manager.c +++ b/src/monitor-manager.c @@ -510,7 +510,13 @@ 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 static gboolean phosh_monitor_manager_handle_apply_monitors_config ( @@ -649,9 +655,3 @@ 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 -- GitLab From 5cbc7151e48020279889c75ddec3e3019e347c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 5 Oct 2018 14:34:52 +0200 Subject: [PATCH 3/8] monitor-manager: On apply extract primary monitor information MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Guido Günther --- src/monitor-manager.c | 146 +++++++++++++++++++++++++++++++++++++++++- src/monitor-manager.h | 2 + 2 files changed, 146 insertions(+), 2 deletions(-) diff --git a/src/monitor-manager.c b/src/monitor-manager.c index 2debd1900..79ce86cc6 100644 --- a/src/monitor-manager.c +++ b/src/monitor-manager.c @@ -518,6 +518,86 @@ phosh_monitor_manager_handle_get_current_state ( #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, @@ -527,9 +607,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); @@ -650,6 +780,18 @@ 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) { diff --git a/src/monitor-manager.h b/src/monitor-manager.h index 4ddf9e6a2..3ca55ac82 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); -- GitLab From daabf72ce86700bcfcbeda15fba2b64d3e9c9e71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 5 Oct 2018 14:34:52 +0200 Subject: [PATCH 4/8] lockscreen-manager: Don't assume primary monitor has index 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Guido Günther --- src/lockscreen-manager.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/lockscreen-manager.c b/src/lockscreen-manager.c index 575db3eaa..1e0814e42 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), -- GitLab From 44ac9364dbb744bd338346927cfed7327fdf2aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 5 Oct 2018 14:34:52 +0200 Subject: [PATCH 5/8] monitor-manager: Fill in proper 'primary' information when reporting monitors and outputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Guido Günther --- src/monitor-manager.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/monitor-manager.c b/src/monitor-manager.c index 79ce86cc6..9574a0480 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); } -- GitLab From 560fa295c09c2787f68d5156b639728800fe99bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 5 Oct 2018 14:34:52 +0200 Subject: [PATCH 6/8] shell: Move panels on primary monitor change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a new primary monitor is set move the panels around. This also fixes the home panel not being disposed. Signed-off-by: Guido Günther --- src/shell.c | 41 ++++++++++++++++++++++++++++++++++++++++- src/shell.h | 1 + 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/shell.c b/src/shell.c index 9b56a9856..95b0cf33d 100644 --- a/src/shell.c +++ b/src/shell.c @@ -61,6 +61,7 @@ typedef struct struct popup *favorites; struct popup *settings; + PhoshMonitor *primary_monitor; PhoshMonitorManager *monitor_manager; PhoshLockscreenManager *lockscreen_manager; } PhoshShellPrivate; @@ -348,6 +349,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) { @@ -448,8 +459,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 (); @@ -550,6 +561,30 @@ 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); +} + + PhoshMonitor * phosh_shell_get_primary_monitor (PhoshShell *self) { @@ -559,6 +594,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 cc0d7712e..f16b10f3f 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 */ -- GitLab From 00e349d060666f8ea2958190579f5ef21169f061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 5 Oct 2018 16:55:56 +0200 Subject: [PATCH 7/8] shell: Make primary monitor a property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes sure we emit signal when it changes so comonents that need to react on panel changes can get a notification. Signed-off-by: Guido Günther --- src/shell.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/shell.c b/src/shell.c index 95b0cf33d..2ba589f11 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]; @@ -422,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; @@ -446,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; @@ -527,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); } @@ -582,6 +596,8 @@ phosh_shell_set_primary_monitor (PhoshShell *self, PhoshMonitor *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]); } -- GitLab From 25500d6ed4b36426a6c19c4c191614409d4b0ec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 5 Oct 2018 17:08:39 +0200 Subject: [PATCH 8/8] system-prompter: Pass on the wl_output and not the monitor to new prompters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes sure they always end up on the primary monitor. Signed-off-by: Guido Günther --- src/system-prompter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system-prompter.c b/src/system-prompter.c index f7c04e6d2..14482be59 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)); } -- GitLab