From defbcebfab0d9e58573e5986db471458a58c35a3 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 20 Mar 2019 15:12:15 +0100 Subject: [PATCH] display: Simplify configuration type and UI selection logic The new logic selects a single configuration type rather than detecting which types can be considered valid. This simplifies the UI rebuilding somewhat, but also changes some internal behaviour. We will now always be in the correct mode internally, even if the UI may not represent this change (i.e. with more than two monitors it always looks the same). --- panels/display/cc-display-panel.c | 130 ++++++++++++++---------------- 1 file changed, 60 insertions(+), 70 deletions(-) diff --git a/panels/display/cc-display-panel.c b/panels/display/cc-display-panel.c index b95a6deea..13ff9ce88 100644 --- a/panels/display/cc-display-panel.c +++ b/panels/display/cc-display-panel.c @@ -49,12 +49,15 @@ #define HEADING_PADDING 12 typedef enum { - /*< flags >*/ - CC_DISPLAY_CONFIG_SINGLE = 0x1, - CC_DISPLAY_CONFIG_JOIN = 0x2, - CC_DISPLAY_CONFIG_CLONE = 0x4, + CC_DISPLAY_CONFIG_SINGLE, + CC_DISPLAY_CONFIG_JOIN, + CC_DISPLAY_CONFIG_CLONE, + + CC_DISPLAY_CONFIG_INVALID_NONE, } CcDisplayConfigType; +#define CC_DISPLAY_CONFIG_LAST_VALID CC_DISPLAY_CONFIG_CLONE + struct _CcDisplayPanel { CcPanel parent_instance; @@ -126,14 +129,12 @@ set_current_output (CcDisplayPanel *panel, static CcDisplayConfigType -config_find_types (CcDisplayPanel *panel) +config_get_current_type (CcDisplayPanel *panel) { - CcDisplayConfigType types = 0; - guint n_outputs, n_active_outputs; + guint n_active_outputs; GList *outputs, *l; outputs = cc_display_config_get_ui_sorted_monitors (panel->current_config); - n_outputs = g_list_length (outputs); n_active_outputs = 0; for (l = outputs; l; l = l->next) { @@ -143,36 +144,15 @@ config_find_types (CcDisplayPanel *panel) n_active_outputs += 1; } - if (n_outputs > (panel->lid_is_closed ? 2 : 1)) - { - if (cc_display_config_is_cloning (panel->current_config)) - types |= CC_DISPLAY_CONFIG_CLONE; - else - { - types |= CC_DISPLAY_CONFIG_JOIN; + if (n_active_outputs == 0) + return CC_DISPLAY_CONFIG_INVALID_NONE; - if (n_active_outputs == 1) - types |= CC_DISPLAY_CONFIG_SINGLE; - } - } - else - { - types |= CC_DISPLAY_CONFIG_SINGLE; - } - - return types; -} - -static CcDisplayConfigType -config_select_type (CcDisplayPanel *panel) -{ - CcDisplayConfigType types = config_find_types (panel); - - if (types & CC_DISPLAY_CONFIG_CLONE) - return CC_DISPLAY_CONFIG_CLONE; - if (types & CC_DISPLAY_CONFIG_SINGLE) + if (n_active_outputs == 1) return CC_DISPLAY_CONFIG_SINGLE; + if (cc_display_config_is_cloning (panel->current_config)) + return CC_DISPLAY_CONFIG_CLONE; + return CC_DISPLAY_CONFIG_JOIN; } @@ -211,14 +191,12 @@ cc_panel_set_selected_type (CcDisplayPanel *panel, CcDisplayConfigType type) static void config_ensure_of_type (CcDisplayPanel *panel, CcDisplayConfigType type) { - CcDisplayConfigType types = config_find_types (panel); + CcDisplayConfigType current_type = config_get_current_type (panel); GList *outputs, *l; - if (type == CC_DISPLAY_CONFIG_SINGLE && (types & CC_DISPLAY_CONFIG_SINGLE)) - return; - - /* Already compatible and not just "single" mode. */ - if (!(types & CC_DISPLAY_CONFIG_SINGLE) && (types & type)) + /* Do not do anything if the current detected configuration type is + * identitcal to what we expect. */ + if (type == current_type) return; reset_current_config (panel); @@ -710,6 +688,7 @@ rebuild_ui (CcDisplayPanel *panel) { guint n_outputs, n_active_outputs, n_usable_outputs; GList *outputs, *l; + CcDisplayConfigType type; panel->rebuilding_counter++; @@ -774,43 +753,54 @@ rebuild_ui (CcDisplayPanel *panel) set_current_output (panel, panel->current_output, TRUE); n_outputs = g_list_length (outputs); + type = config_get_current_type (panel); - /* We only show the top chooser with two outputs (and never if the lid is closed). - * And only in that mode do we allow mirroring. */ - if (n_outputs == 2 && !panel->lid_is_closed) + if (n_outputs == 2 && n_usable_outputs == 2) { + /* We only show the top chooser with two monitors that are + * both usable (i.e. two monitors incl. internal and lid not closed). + * In this case, the arrangement widget is shown if we are in JOIN mode. + */ + if (type > CC_DISPLAY_CONFIG_LAST_VALID) + type = CC_DISPLAY_CONFIG_JOIN; + gtk_widget_set_visible (panel->config_type_switcher_frame, TRUE); + gtk_widget_set_visible (panel->arrangement_frame, type == CC_DISPLAY_CONFIG_JOIN); - cc_panel_set_selected_type (panel, config_select_type (panel)); - } - else - { - gtk_widget_set_visible (panel->config_type_switcher_frame, FALSE); - if (n_outputs == (panel->lid_is_closed ? 2 : 1)) - cc_panel_set_selected_type (panel, CC_DISPLAY_CONFIG_SINGLE); - else - cc_panel_set_selected_type (panel, CC_DISPLAY_CONFIG_JOIN); - } - - - gtk_widget_set_visible (panel->arrangement_frame, cc_panel_get_selected_type (panel) == CC_DISPLAY_CONFIG_JOIN); - - if (panel->lid_is_closed) - { - if (n_outputs <= 2 || cc_panel_get_selected_type (panel) == CC_DISPLAY_CONFIG_CLONE) + /* We need a switcher except in CLONE mode */ + if (type == CC_DISPLAY_CONFIG_CLONE) gtk_stack_set_visible_child_name (panel->output_selection_stack, "no-selection"); else - gtk_stack_set_visible_child_name (panel->output_selection_stack, "multi-selection"); - } - else - { - if (n_outputs == 1 || cc_panel_get_selected_type (panel) == CC_DISPLAY_CONFIG_CLONE) - gtk_stack_set_visible_child_name (panel->output_selection_stack, "no-selection"); - else if (n_outputs == 2) gtk_stack_set_visible_child_name (panel->output_selection_stack, "two-selection"); - else - gtk_stack_set_visible_child_name (panel->output_selection_stack, "multi-selection"); } + else if (n_usable_outputs > 1) + { + /* We have more than one usable monitor. In this case there is no chooser, + * and we always show the arrangement widget even if we are in SINGLE mode. + */ + gtk_widget_set_visible (panel->config_type_switcher_frame, FALSE); + gtk_widget_set_visible (panel->arrangement_frame, TRUE); + + /* Mirror is also invalid as it cannot be configured using this UI. */ + if (type == CC_DISPLAY_CONFIG_CLONE || type > CC_DISPLAY_CONFIG_LAST_VALID) + type = CC_DISPLAY_CONFIG_JOIN; + + gtk_stack_set_visible_child_name (panel->output_selection_stack, "multi-selection"); + } + else + { + /* We only have a single usable monitor, show neither configuration type + * switcher nor arrangement widget and ensure we really are in SINGLE + * mode (and not e.g. mirroring across one display) */ + type = CC_DISPLAY_CONFIG_SINGLE; + + gtk_widget_set_visible (panel->config_type_switcher_frame, FALSE); + gtk_widget_set_visible (panel->arrangement_frame, FALSE); + + gtk_stack_set_visible_child_name (panel->output_selection_stack, "no-selection"); + } + + cc_panel_set_selected_type (panel, type); panel->rebuilding_counter--; update_apply_button (panel);