Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

power: Add support for ALS profiles #11

Open
wants to merge 1 commit into
base: droidian
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 137 additions & 13 deletions panels/power/cc-power-panel.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ struct _CcPowerPanel
CcPanel parent_instance;

AdwSwitchRow *als_row;
AdwActionRow *als_row_light;
AdwActionRow *als_row_medium;
AdwActionRow *als_row_high;
AdwActionRow *als_row_device;
GtkWindow *automatic_suspend_dialog;
CcListRow *automatic_suspend_row;
GtkListBox *battery_listbox;
Expand Down Expand Up @@ -100,6 +104,37 @@ enum
ACTION_MODEL_VALUE
};

/* We used python to get values as bytes:
from gi.repository import GLib
variant = GLib.Variant("a{ii}", { 1: 2, ...})
bytes = variant.get_data_as_bytes()
print("static const uint8_t x[] = {{\n{}\n}};".format(", ".join([format(b, '#04x') for b in bytes.get_data()])))
*/
/* {0:1,1000:12,3000:19,5000:30,7000:46,8000:57,9000:71,10000:100} */
static const uint8_t LOW_BRIGHTNESS[] = {
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0xb8, 0x0b, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x88, 0x13, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x58, 0x1b, 0x00, 0x00,
0x2e, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
0x28, 0x23, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00,
0x64, 0x00, 0x00, 0x00
};
/* {0:12,1500:19,2500:30,3500:46,4000:57,4500:71,5000:100} */
static const uint8_t MEDIUM_BRIGHTNESS[] = {
0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xdc, 0x05, 0x00, 0x00,
0x13, 0x00, 0x00, 0x00, 0xc4, 0x09, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
0xac, 0x0d, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x00, 0x00,
0x39, 0x00, 0x00, 0x00, 0x94, 0x11, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00,
0x88, 0x13, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00
};
/* {0:25,1000:30,2000:46,2250:70,2500:100} */
static const uint8_t HIGH_BRIGHTNESS[] = {
0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x00, 0xd0, 0x07, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
0xca, 0x08, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0xc4, 0x09, 0x00, 0x00,
0x64, 0x00, 0x00, 0x00
};

static const char *
cc_power_panel_get_help_uri (CcPanel *panel)
{
Expand Down Expand Up @@ -304,15 +339,6 @@ up_client_device_added (CcPowerPanel *self,
up_client_changed (self);
}

static void
als_row_changed_cb (CcPowerPanel *self)
{
gboolean enabled;
enabled = adw_switch_row_get_active (self->als_row);
g_debug ("Setting ALS enabled %s", enabled ? "on" : "off");
g_settings_set_boolean (self->gsd_settings, "ambient-enabled", enabled);
}

static void
als_enabled_state_changed (CcPowerPanel *self)
{
Expand All @@ -331,10 +357,7 @@ als_enabled_state_changed (CcPowerPanel *self)

enabled = g_settings_get_boolean (self->gsd_settings, "ambient-enabled");
g_debug ("ALS enabled: %s", enabled ? "on" : "off");
g_signal_handlers_block_by_func (self->als_row, als_row_changed_cb, self);
adw_switch_row_set_active (self->als_row, enabled);
gtk_widget_set_visible (GTK_WIDGET (self->als_row), visible && self->has_brightness);
g_signal_handlers_unblock_by_func (self->als_row, als_row_changed_cb, self);
}

static void
Expand Down Expand Up @@ -454,6 +477,28 @@ set_value_for_combo_row (AdwComboRow *combo_row, gint value)
adw_combo_row_set_selected (combo_row, insert_before);
}

static GVariant*
get_variant_from_uint8_array (const uint8_t points[], gsize size)
{
GVariant *value = NULL;
g_autoptr (GVariantType) type = NULL;
g_autoptr (GBytes) bytes = NULL;

bytes = g_bytes_new (points, size);
type = g_variant_type_new ("a{ii}");
value = g_variant_new_from_bytes (type, bytes, TRUE);

return g_variant_ref (value);
}

static void
set_brightness_value (CcPowerPanel *self, const uint8_t points[], gsize size)
{
g_settings_set_value (self->gsd_settings,
"ambient-brightness-points",
get_variant_from_uint8_array (points, size));
}

static void
set_ac_battery_ui_mode (CcPowerPanel *self)
{
Expand Down Expand Up @@ -521,6 +566,27 @@ blank_screen_row_changed_cb (CcPowerPanel *self)
g_settings_set_uint (self->session_settings, "idle-delay", value);
}

static void
als_radio_activated_cb (CcPowerPanel *self,
gpointer user_data)
{
AdwActionRow *row = ADW_ACTION_ROW (user_data);

if (row == self->als_row_light) {
set_brightness_value (self, LOW_BRIGHTNESS, sizeof (LOW_BRIGHTNESS));
} else if (row == self->als_row_medium) {
set_brightness_value (self, MEDIUM_BRIGHTNESS, sizeof (MEDIUM_BRIGHTNESS));
} else if (row == self->als_row_high) {
set_brightness_value (self, HIGH_BRIGHTNESS, sizeof (HIGH_BRIGHTNESS));
} else {
g_settings_set_value (self->gsd_settings,
"ambient-brightness-points",
g_settings_get_default_value (
self->gsd_settings,
"ambient-brightness-points"));
}
}

static void
power_saver_radio_activated_cb (CcPowerPanel *self,
gpointer user_data)
Expand Down Expand Up @@ -1378,6 +1444,53 @@ setup_general_section (CcPowerPanel *self)
gtk_widget_set_visible (GTK_WIDGET (self->general_section), show_section);
}

static void
setup_ambient_radio (CcPowerPanel *self)
{
const uint8_t* br[] = {
LOW_BRIGHTNESS,
MEDIUM_BRIGHTNESS,
HIGH_BRIGHTNESS
};
const unsigned int br_length[] = {
sizeof (LOW_BRIGHTNESS),
sizeof (MEDIUM_BRIGHTNESS),
sizeof (HIGH_BRIGHTNESS)
};
AdwActionRow* wg[] = {
self->als_row_light,
self->als_row_medium,
self->als_row_high
};
unsigned int length = sizeof (br) / sizeof (br[0]);
g_autoptr (GVariant) setting = g_settings_get_value (
self->gsd_settings,
"ambient-brightness-points");
GVariant *value;
gboolean optimized_visible;

value = g_settings_get_default_value (self->gsd_settings,
"ambient-brightness-points");
optimized_visible = g_variant_get_size (value) > 1;
gtk_widget_set_visible (GTK_WIDGET (self->als_row_device), optimized_visible);
g_variant_unref (value);

for (int i = 0; i < length; i++) {
value = get_variant_from_uint8_array (br[i], br_length[i]);

if (g_variant_equal (value, setting)) {
adw_action_row_activate (wg[i]);
g_variant_unref (value);
return;
}

g_variant_unref (value);
}

if (optimized_visible)
adw_action_row_activate (self->als_row_device);
}

static gint
battery_sort_func (GtkListBoxRow *a, GtkListBoxRow *b, gpointer data)
{
Expand Down Expand Up @@ -1441,6 +1554,10 @@ cc_power_panel_class_init (CcPowerPanelClass *klass)
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/power/cc-power-panel.ui");

gtk_widget_class_bind_template_child (widget_class, CcPowerPanel, als_row);
gtk_widget_class_bind_template_child (widget_class, CcPowerPanel, als_row_light);
gtk_widget_class_bind_template_child (widget_class, CcPowerPanel, als_row_medium);
gtk_widget_class_bind_template_child (widget_class, CcPowerPanel, als_row_high);
gtk_widget_class_bind_template_child (widget_class, CcPowerPanel, als_row_device);
gtk_widget_class_bind_template_child (widget_class, CcPowerPanel, automatic_suspend_dialog);
gtk_widget_class_bind_template_child (widget_class, CcPowerPanel, automatic_suspend_row);
gtk_widget_class_bind_template_child (widget_class, CcPowerPanel, battery_listbox);
Expand Down Expand Up @@ -1469,7 +1586,7 @@ cc_power_panel_class_init (CcPowerPanelClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcPowerPanel, suspend_on_ac_delay_combo);
gtk_widget_class_bind_template_child (widget_class, CcPowerPanel, suspend_on_ac_switch_row);

gtk_widget_class_bind_template_callback (widget_class, als_row_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, als_radio_activated_cb);
gtk_widget_class_bind_template_callback (widget_class, blank_screen_row_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, power_saver_radio_activated_cb);
gtk_widget_class_bind_template_callback (widget_class, keynav_failed_cb);
Expand Down Expand Up @@ -1534,6 +1651,13 @@ cc_power_panel_init (CcPowerPanel *self)
G_SETTINGS_BIND_DEFAULT);
}



g_settings_bind (self->gsd_settings, "ambient-enabled",
self->als_row, "enable-expansion",
G_SETTINGS_BIND_DEFAULT);
setup_ambient_radio (self);

setup_general_section (self);

/* populate batteries */
Expand Down
60 changes: 58 additions & 2 deletions panels/power/cc-power-panel.ui
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,67 @@
<object class="AdwPreferencesGroup" id="power_saving_section">
<property name="title" translatable="yes">Power Saving</property>
<child>
<object class="AdwSwitchRow" id="als_row">
<object class="AdwExpanderRow" id="als_row">
<property name="title" translatable="yes">A_utomatic Screen Brightness</property>
<property name="subtitle" translatable="yes">Adjust screen brightness to the surrounding light</property>
<property name="use_underline">True</property>
<signal name="notify::active" handler="als_row_changed_cb" object="CcPowerPanel" swapped="yes"/>
<property name="show_enable_switch">True</property>
<child>
<object class="AdwActionRow" id="als_row_light">
<property name="activatable_widget">als_radio_light</property>
<property name="title" translatable="yes">Low brightness</property>
<signal name="activated" handler="als_radio_activated_cb" object="CcPowerPanel" swapped="yes"/>
<child type="prefix">
<object class="GtkCheckButton" id="als_radio_light">
<property name="valign">center</property>
<property name="active">True</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="als_row_medium">
<property name="activatable_widget">als_radio_medium</property>
<property name="title" translatable="yes">Medium brightness</property>
<signal name="activated" handler="als_radio_activated_cb" object="CcPowerPanel" swapped="yes"/>
<child type="prefix">
<object class="GtkCheckButton" id="als_radio_medium">
<property name="group">als_radio_light</property>
<property name="valign">center</property>
<property name="active">True</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="als_row_high">
<property name="activatable_widget">als_radio_high</property>
<property name="title" translatable="yes">High brightness</property>
<signal name="activated" handler="als_radio_activated_cb" object="CcPowerPanel" swapped="yes"/>
<child type="prefix">
<object class="GtkCheckButton" id="als_radio_high">
<property name="group">als_radio_light</property>
<property name="valign">center</property>
<property name="active">True</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="als_row_device">
<property name="visible">False</property>
<property name="activatable_widget">als_radio_device</property>
<property name="title" translatable="yes">Optimized brightness</property>
<signal name="activated" handler="als_radio_activated_cb" object="CcPowerPanel" swapped="yes"/>
<child type="prefix">
<object class="GtkCheckButton" id="als_radio_device">
<property name="group">als_radio_light</property>
<property name="valign">center</property>
<property name="active">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
Expand Down