static void
task_title_setup (TaskTitle *title)
{
    TaskTitlePrivate *priv = title->priv;

    priv->screen = wnck_screen_get_default ();
    priv->window = NULL;
    gtk_widget_add_events (GTK_WIDGET (title), GDK_ALL_EVENTS_MASK);
    priv->align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
    gtk_alignment_set_padding (GTK_ALIGNMENT (priv->align),
        0, 0, 6, 6);
    gtk_container_add (GTK_CONTAINER (title), priv->align);
    priv->grid = gtk_grid_new();
    gtk_grid_set_row_spacing (GTK_GRID(priv->grid), 2);
    gtk_container_add (GTK_CONTAINER (priv->align), priv->grid);
    gtk_widget_set_no_show_all (priv->grid, TRUE);
    gtk_widget_show (priv->grid);

    //Prepare and show the title label
    priv->label = getTitleLabel();
    gtk_grid_attach (GTK_GRID(priv->grid), priv->label, 0, 0, 1, 1);
    gtk_widget_show (priv->label);

    //Create the close button
    priv->button = getCloseButton (title);
    gtk_grid_attach (GTK_GRID(priv->grid), priv->button, 1, 0, 1, 1);
    gtk_widget_show (priv->button);

    g_signal_connect (GTK_WIDGET(title), "draw",
        G_CALLBACK (on_draw), title);

    // Prepare and add the logoff icon to the title
    GdkScreen *gdkscreen = gtk_widget_get_screen (GTK_WIDGET (title));
    GtkIconTheme *theme = gtk_icon_theme_get_for_screen (gdkscreen);
    //this shows a little green exit icon, like the ones on emergency exits
    priv->quit_icon = gtk_icon_theme_load_icon (
        theme, "gnome-logout", 16, 0, NULL
    );
    priv->button_image = gtk_image_new_from_pixbuf (priv->quit_icon);
    gtk_container_add (GTK_CONTAINER (priv->button), priv->button_image);
    gtk_widget_show (priv->button_image);
    gtk_widget_set_tooltip_text (priv->button,
        _("Log off, switch user, lock screen or "
        "power down the computer")
    );
    gtk_widget_set_tooltip_text (GTK_WIDGET (title), _("Home"));
    gtk_widget_add_events (GTK_WIDGET (title), GDK_ALL_EVENTS_MASK);
    g_signal_connect (priv->screen, "active-window-changed",
        G_CALLBACK (on_active_window_changed), title);
    g_signal_connect (title, "button-press-event",
        G_CALLBACK (on_button_press), NULL);
}
 virtual void needsLayout(void)
 {
     if (!_parentInited) {
         return;
     }
     // Hide the background and the label
     if (getTitleLabel() != nullptr) {
         getTitleLabel()->setVisible(false);
     }
     if (getBackgroundSprite()) {
         getBackgroundSprite()->setVisible(false);
     }
     // Update anchor of all labels
     this->setLabelAnchorPoint(this->_labelAnchorPoint);
     
     // Update the label to match with the current state
     _currentTitle = getTitleForState(_state);
     
     _currentTitleColor = getTitleColorForState(_state);
     
     this->setTitleLabel(getTitleLabelForState(_state));
     
     LabelProtocol* label = dynamic_cast<LabelProtocol*>(getTitleLabel());
     if (label && !_currentTitle.empty())
     {
         label->setString(_currentTitle);
     }
     
     if (getTitleLabel())
     {
         getTitleLabel()->setColor(_currentTitleColor);
     }
     if (getTitleLabel() != nullptr)
     {
         getTitleLabel()->setPosition(Point (getContentSize().width / 2, getContentSize().height / 2));
     }
     
     // Update the background sprite
     this->setBackgroundSprite(this->getBackgroundSpriteForState(_state));
     if (getBackgroundSprite() != nullptr)
     {
         getBackgroundSprite()->setPosition(Point (getContentSize().width / 2, getContentSize().height / 2));
     }
     
     // Get the title label size
     Size titleLabelSize;
     if (getTitleLabel() != nullptr)
     {
         titleLabelSize = getTitleLabel()->getBoundingBox().size;
     }
     
     // Adjust the background image if necessary
     if (_doesAdjustBackgroundImage)
     {
         // Add the margins
         if (getBackgroundSprite() != nullptr)
         {
             getBackgroundSprite()->setContentSize(Size(titleLabelSize.width + _marginH * 2, titleLabelSize.height + _marginV * 2));
         }
     }
     else
     {
         //TODO: should this also have margins if one of the preferred sizes is relaxed?
         if (getBackgroundSprite() != nullptr)
         {
             Size preferredSize = getBackgroundSprite()->getPreferredSize();
             if (preferredSize.width <= 0)
             {
                 preferredSize.width = titleLabelSize.width;
             }
             if (preferredSize.height <= 0)
             {
                 preferredSize.height = titleLabelSize.height;
             }
             
             getBackgroundSprite()->setContentSize(preferredSize);
         }
     }
     
     // Set the content size
     Rect rectTitle;
     if (getTitleLabel() != nullptr)
     {
         rectTitle = getTitleLabel()->getBoundingBox();
     }
     Rect rectBackground;
     if (getBackgroundSprite() != nullptr)
     {
         rectBackground = getBackgroundSprite()->getBoundingBox();
     }
     
     Rect maxRect = ControlUtils::RectUnion(rectTitle, rectBackground);
     if (_maxSize.width > 0 && maxRect.size.width > _maxSize.width)
         maxRect.size.width = _maxSize.width;
     
     if (_maxSize.height > 0 && maxRect.size.height > _maxSize.height)
         maxRect.size.height = _maxSize.height;
     
     if (titleLabelSize.width > maxRect.size.width - _horizonPadding * 2)
         maxRect.size.width += _horizonPadding * 2;
     
     if (titleLabelSize.height > maxRect.size.height - _verticalPadding * 2)
         maxRect.size.height += _verticalPadding * 2;
     
     setContentSize(Size(maxRect.size.width, maxRect.size.height));
     
     if (getTitleLabel() != nullptr)
     {
         getTitleLabel()->setPosition(Point(getContentSize().width/2, getContentSize().height/2));
         // Make visible the background and the label
         getTitleLabel()->setVisible(true);
     }
     
     if (getBackgroundSprite() != nullptr)
     {
         getBackgroundSprite()->setPosition(Point(getContentSize().width/2, getContentSize().height/2));
         getBackgroundSprite()->setVisible(true);
         getBackgroundSprite()->setContentSize(maxRect.size);
     }
 }
 void setTitleOutlineColor(Color4B color) {
     Label *titleLabel = dynamic_cast<Label*>(getTitleLabel());
     if (titleLabel) {
         titleLabel->enableOutline(color);
     }
 }