Skip to content
Snippets Groups Projects
power-manager-button.c 43.8 KiB
Newer Older
    xfce_dialog_show_help_with_version (NULL, "xfce4-power-manager", "start", NULL, XFPM_VERSION_SHORT);
Eric Koegel's avatar
Eric Koegel committed
void
power_manager_button_show (PowerManagerButton *button)
    g_return_if_fail (POWER_MANAGER_IS_BUTTON (button));
#ifdef XFCE_PLUGIN
    xfce_panel_plugin_add_action_widget (button->priv->plugin, GTK_WIDGET (button));
    xfce_panel_plugin_set_small (button->priv->plugin, TRUE);
    button->priv->panel_icon_image = gtk_image_new ();
    gtk_container_add (GTK_CONTAINER (button), button->priv->panel_icon_image);
    mi = gtk_menu_item_new_with_mnemonic (_("_Help"));
    gtk_widget_set_sensitive (mi, TRUE);
    gtk_widget_show (mi);
    g_signal_connect (mi, "activate", G_CALLBACK (help_cb), button);

#ifdef XFCE_PLUGIN
    xfce_panel_plugin_menu_insert_item (button->priv->plugin, GTK_MENU_ITEM (mi));

    g_signal_connect (button->priv->plugin, "size-changed",
                      G_CALLBACK (power_manager_button_size_changed_cb), button);
    g_signal_connect (button->priv->plugin, "style-updated",
                      G_CALLBACK (power_manager_button_style_update_cb), button);
    g_signal_connect (button->priv->plugin, "free-data",
                      G_CALLBACK (power_manager_button_free_data_cb), button);

    gtk_widget_show_all (GTK_WIDGET(button));
    power_manager_button_set_tooltip (button);

    /* Add all the devcies currently attached to the system */
    power_manager_button_add_all_devices (button);
menu_destroyed_cb(GtkMenuShell *menu, gpointer user_data)
    PowerManagerButton *button = POWER_MANAGER_BUTTON (user_data);
    TRACE("entering");
    /* menu destroyed, range slider is gone */
    button->priv->range = NULL;

    /* untoggle panel icon */
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), FALSE);
    button->priv->menu = NULL;
}

static void
menu_item_destroyed_cb(GtkWidget *object, gpointer user_data)
{
    PowerManagerButton *button = POWER_MANAGER_BUTTON (user_data);
    GList *item;

    for (item = g_list_first (button->priv->devices); item != NULL; item = g_list_next (item))
    {
        BatteryDevice *battery_device = item->data;

        if (battery_device->menu_item == object)
        {
            battery_device->menu_item = NULL;
            return;
        }
    }
}

static void
menu_item_activate_cb(GtkWidget *object, gpointer user_data)
{
    PowerManagerButton *button = POWER_MANAGER_BUTTON (user_data);
    GList *item;

    for (item = g_list_first (button->priv->devices); item != NULL; item = g_list_next (item))
    {
        BatteryDevice *battery_device = item->data;

        if (battery_device->menu_item == object)
        {
            /* Call xfpm settings with the device id */
            xfpm_preferences_device_id (battery_device->object_path);
            return;
        }
    }
}

static gboolean
power_manager_button_menu_add_device (PowerManagerButton *button, BatteryDevice *battery_device, gboolean append)
    g_return_val_if_fail (POWER_MANAGER_IS_BUTTON (button), FALSE);

    /* We need a menu to attach it to */
    g_return_val_if_fail (button->priv->menu, FALSE);
    if (UP_IS_DEVICE (battery_device->device))
    {
        g_object_get (battery_device->device,
                      "kind", &type,
                      NULL);
        /* Don't add the display device or line power to the menu */
        if (type == UP_DEVICE_KIND_LINE_POWER || battery_device->device == button->priv->display_device)
        {
            DBG("filtering device from menu (display or line power device)");
            return FALSE;
        }
    }
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
    mi = gtk_image_menu_item_new_with_label(battery_device->details);
G_GNUC_END_IGNORE_DEPRECATIONS
    /* Make the menu item be bold and multi-line */
    label = gtk_bin_get_child (GTK_BIN (mi));
    gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
    /* add the image */
    battery_device->img = gtk_image_new_from_pixbuf (battery_device->pix);
    g_object_ref (battery_device->img);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), battery_device->img);
G_GNUC_END_IGNORE_DEPRECATIONS
    /* keep track of the menu item in the battery_device so we can update it */
    battery_device->menu_item = mi;
    g_signal_connect(G_OBJECT (mi), "destroy", G_CALLBACK (menu_item_destroyed_cb), button);
    battery_device->expose_signal_id = g_signal_connect_after (G_OBJECT (battery_device->img),
                                                               G_CALLBACK (power_manager_button_device_icon_expose),
                                                               battery_device->device);
    /* Active calls xfpm settings with the device's id to display details */
    g_signal_connect(G_OBJECT(mi), "activate", G_CALLBACK(menu_item_activate_cb), button);

    /* Add it to the menu */
        gtk_menu_shell_append (GTK_MENU_SHELL(button->priv->menu), mi);
        gtk_menu_shell_prepend (GTK_MENU_SHELL(button->priv->menu), mi);
decrease_brightness (PowerManagerButton *button)
{
    gint32 level;

    TRACE("entering");

    if ( !xfpm_brightness_has_hw (button->priv->brightness) )
        return;

    xfpm_brightness_get_level (button->priv->brightness, &level);

    if ( level > button->priv->brightness_min_level )
    {
        xfpm_brightness_down (button->priv->brightness, &level);
        if (button->priv->range)
            gtk_range_set_value (GTK_RANGE (button->priv->range), level);
    }
}

static void
increase_brightness (PowerManagerButton *button)
    if (!xfpm_brightness_has_hw (button->priv->brightness))
        return;

    max_level = xfpm_brightness_get_max_level (button->priv->brightness);
    xfpm_brightness_get_level (button->priv->brightness, &level);

    if (level < max_level)
    {
        xfpm_brightness_up (button->priv->brightness, &level);
        if (button->priv->range)
            gtk_range_set_value (GTK_RANGE (button->priv->range), level);
    }
}

brightness_set_level_with_timeout (PowerManagerButton *button)
{
    gint32 range_level, hw_level;

    TRACE("entering");

    range_level = (gint32) gtk_range_get_value (GTK_RANGE (button->priv->range));

    xfpm_brightness_get_level (button->priv->brightness, &hw_level);

    if (hw_level != range_level)
    {
        xfpm_brightness_set_level (button->priv->brightness, range_level);
    }

    if (button->priv->set_level_timeout)
    {
        g_source_remove(button->priv->set_level_timeout);
        button->priv->set_level_timeout = 0;
    }

    return FALSE;
}

static void
range_value_changed_cb (PowerManagerButton *button, GtkWidget *widget)
{
    TRACE("entering");

    if (button->priv->set_level_timeout)
        return;

    button->priv->set_level_timeout =
        g_timeout_add (SET_LEVEL_TIMEOUT,
                       (GSourceFunc) brightness_set_level_with_timeout, button);
range_scroll_cb (GtkWidget *widget, GdkEvent *event, PowerManagerButton *button)
{
    GdkEventScroll *scroll_event;

    TRACE("entering");

    scroll_event = (GdkEventScroll*)event;

    if (scroll_event->direction == GDK_SCROLL_UP)
        increase_brightness (button);
    else if (scroll_event->direction == GDK_SCROLL_DOWN)
        decrease_brightness (button);
}

static void
range_show_cb (GtkWidget *widget, PowerManagerButton *button)
    GdkDeviceManager* manager = gdk_display_get_device_manager (gdk_display_get_default());
    GdkDevice* pointer = gdk_device_manager_get_client_pointer (manager);
    /* Release these grabs as they will cause a lockup if pkexec is called
     * for the brightness helper */
        gdk_device_ungrab (pointer, GDK_CURRENT_TIME);

    gtk_grab_remove (widget);
power_manager_button_show_menu (PowerManagerButton *button)
Eric Koegel's avatar
Eric Koegel committed
    GtkWidget *menu, *mi, *img = NULL;
Eric Koegel's avatar
Eric Koegel committed
    GdkScreen *gscreen;
    GList *item;
    gboolean show_separator_flag = FALSE;
    gint32 max_level, current_level = 0;
    TRACE("entering");

    g_return_if_fail (POWER_MANAGER_IS_BUTTON (button));

    if (gtk_widget_has_screen (GTK_WIDGET (button)))
Eric Koegel's avatar
Eric Koegel committed
        gscreen = gtk_widget_get_screen(GTK_WIDGET(button));
    else
        gscreen = gdk_display_get_default_screen(gdk_display_get_default());

    menu = gtk_menu_new ();
    gtk_menu_set_screen(GTK_MENU(menu), gscreen);
    /* keep track of the menu while it's being displayed */
    button->priv->menu = menu;
    g_signal_connect(GTK_MENU_SHELL(menu), "deactivate", G_CALLBACK(menu_destroyed_cb), button);
Eric Koegel's avatar
Eric Koegel committed

    for (item = g_list_first (button->priv->devices); item != NULL; item = g_list_next (item))
    {
        BatteryDevice *battery_device = item->data;

        if (power_manager_button_menu_add_device (button, battery_device, TRUE))
        {
            /* If we add an item to the menu, show the separator */
            show_separator_flag = TRUE;
        }
    if (show_separator_flag)
    {
        /* separator */
        mi = gtk_separator_menu_item_new ();
        gtk_widget_show (mi);
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
    }

    /* Display brightness slider - show if there's hardware support for it */
    if ( xfpm_brightness_has_hw (button->priv->brightness) )
    {
Eric Koegel's avatar
Eric Koegel committed
        max_level = xfpm_brightness_get_max_level (button->priv->brightness);

        mi = scale_menu_item_new_with_range (button->priv->brightness_min_level, max_level, 1);
        scale_menu_item_set_description_label (SCALE_MENU_ITEM (mi), _("<b>Display brightness</b>"));
Eric Koegel's avatar
Eric Koegel committed
        button->priv->range = scale_menu_item_get_scale (SCALE_MENU_ITEM (mi));

        /* update the slider to the current brightness level */
        xfpm_brightness_get_level (button->priv->brightness, &current_level);
        gtk_range_set_value (GTK_RANGE (button->priv->range), current_level);
        g_signal_connect_swapped (mi, "value-changed", G_CALLBACK (range_value_changed_cb), button);
        g_signal_connect (mi, "scroll-event", G_CALLBACK (range_scroll_cb), button);
        g_signal_connect (menu, "show", G_CALLBACK (range_show_cb), button);

        /* load and display the brightness icon and force it to 32px size */
        img = gtk_image_new_from_icon_name (XFPM_DISPLAY_BRIGHTNESS_ICON, GTK_ICON_SIZE_DND);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM(mi), img);
G_GNUC_END_IGNORE_DEPRECATIONS
        gtk_image_set_pixel_size (GTK_IMAGE (img), 32);
        gtk_widget_show_all (mi);
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
    /* Presentation mode checkbox */
    mi = gtk_check_menu_item_new_with_mnemonic (_("Presentation _mode"));
    gtk_widget_set_sensitive (mi, TRUE);
    gtk_widget_show (mi);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
    xfconf_g_property_bind(button->priv->channel,
                           PROPERTIES_PREFIX PRESENTATION_MODE,
                           G_TYPE_BOOLEAN, G_OBJECT(mi), "active");

    /* Power manager settings */
    mi = gtk_menu_item_new_with_mnemonic (_("_Power manager settings..."));
    gtk_widget_show (mi);
    gtk_menu_shell_append (GTK_MENU_SHELL(menu), mi);
    g_signal_connect (G_OBJECT(mi), "activate", G_CALLBACK(xfpm_preferences), NULL);
Eric Koegel's avatar
Eric Koegel committed

    gtk_menu_popup (GTK_MENU (menu),
                    NULL,
                    NULL,
#ifdef XFCE_PLUGIN
                    xfce_panel_plugin_position_menu,
#else
                    NULL,
#endif
#ifdef XFCE_PLUGIN
                    button->priv->plugin,
                    0,
                    gtk_get_current_event_time ());