summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew P. <pan.pav.7c5@gmail.com>2014-06-09 18:49:08 +0300
committerAndrew P. <pan.pav.7c5@gmail.com>2014-06-09 18:49:08 +0300
commitc8d2ac4112d362b59714e224300b78a7b6e14155 (patch)
treed27a7b43d83fc7ebb0c1748162ce9273367bb0c7
parent35c44a0385bbac555d6f2dda16cdf20471040d8c (diff)
parent076d8fc3b76e3c2797ecdca85375e5d16b900a64 (diff)
downloadlightdm-gtk-greeter-git-c8d2ac4112d362b59714e224300b78a7b6e14155.tar.gz
Merged "new panel layout" branch
-rw-r--r--src/Makefile.am3
-rw-r--r--src/greeter_menu_bar.xml8
-rw-r--r--src/greetermenubar.c342
-rw-r--r--src/greetermenubar.h37
-rw-r--r--src/lightdm-gtk-greeter.c255
5 files changed, 567 insertions, 78 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index a8d3393..f2752a9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,7 +7,8 @@ lightdm_gtk_greeter_built_sources = \
lightdm_gtk_greeter_SOURCES = \
$(lightdm_gtk_greeter_built_sources) \
- lightdm-gtk-greeter.c
+ lightdm-gtk-greeter.c \
+ greetermenubar.c
AM_CPPFLAGS = \
-I$(top_srcdir) \
diff --git a/src/greeter_menu_bar.xml b/src/greeter_menu_bar.xml
new file mode 100644
index 0000000..a009c1a
--- /dev/null
+++ b/src/greeter_menu_bar.xml
@@ -0,0 +1,8 @@
+<glade-catalog name="greeter_menu_bar" domain="glade-3"
+ depends="gtk+" version="1.0">
+ <glade-widget-classes>
+ <glade-widget-class title="Greeter MenuBar" name="GreeterMenuBar"
+ generic-name="GreeterMenuBar" parent="GtkMenuBar"
+ icon-name="widget-gtk-window"/>
+ </glade-widget-classes>
+</glade-catalog>
diff --git a/src/greetermenubar.c b/src/greetermenubar.c
new file mode 100644
index 0000000..dd383e5
--- /dev/null
+++ b/src/greetermenubar.c
@@ -0,0 +1,342 @@
+#include <gtk/gtk.h>
+#include "greetermenubar.h"
+
+
+static void greeter_menu_bar_size_allocate(GtkWidget* widget, GtkAllocation* allocation);
+
+G_DEFINE_TYPE(GreeterMenuBar, greeter_menu_bar, GTK_TYPE_MENU_BAR);
+
+static void
+greeter_menu_bar_class_init(GreeterMenuBarClass* klass)
+{
+ GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
+ widget_class->size_allocate = greeter_menu_bar_size_allocate;
+}
+
+static void
+greeter_menu_bar_init(GreeterMenuBar* square)
+{
+
+}
+
+GtkWidget*
+greeter_menu_bar_new()
+{
+ return GTK_WIDGET(g_object_new(greeter_menu_bar_get_type(), NULL));
+}
+
+#if GTK_CHECK_VERSION (3, 0, 0)
+static gint
+sort_minimal_size(gconstpointer a, gconstpointer b, GtkRequestedSize* sizes)
+{
+ gint a_size = sizes[GPOINTER_TO_INT(a)].natural_size;
+ gint b_size = sizes[GPOINTER_TO_INT(b)].natural_size;
+ return a_size == b_size ? 0 : a_size > b_size ? -1 : +1;
+}
+
+static void
+greeter_menu_bar_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
+{
+ GList* item;
+ GList* shell_children;
+ GList* expand_nums = NULL;
+ guint visible_count = 0, expand_count = 0;
+
+ g_return_if_fail(allocation != NULL);
+ g_return_if_fail(GREETER_IS_MENU_BAR(widget));
+
+ gtk_widget_set_allocation(widget, allocation);
+
+ GtkPackDirection pack_direction = gtk_menu_bar_get_pack_direction(GTK_MENU_BAR(widget));
+ g_return_if_fail(pack_direction == GTK_PACK_DIRECTION_LTR || pack_direction == GTK_PACK_DIRECTION_RTL);
+
+ shell_children = gtk_container_get_children(GTK_CONTAINER(widget));
+
+ for(item = shell_children; item; item = g_list_next(item))
+ if(gtk_widget_get_visible(item->data))
+ {
+ if(gtk_widget_compute_expand(item->data, GTK_ORIENTATION_HORIZONTAL))
+ {
+ expand_nums = g_list_prepend(expand_nums, GINT_TO_POINTER(visible_count));
+ expand_count++;
+ }
+ visible_count++;
+ }
+
+ if(gtk_widget_get_realized(widget))
+ gdk_window_move_resize(gtk_widget_get_window(widget),
+ allocation->x, allocation->y,
+ allocation->width, allocation->height);
+
+ if(visible_count > 0)
+ {
+ GtkAllocation remaining_space;
+ GtkStyleContext* context = gtk_widget_get_style_context(widget);
+ GtkStateFlags flags = gtk_widget_get_state_flags(widget);
+ GtkRequestedSize* requested_sizes = g_newa(GtkRequestedSize, visible_count);
+ guint border_width = gtk_container_get_border_width(GTK_CONTAINER(widget));
+ GtkShadowType shadow_type = GTK_SHADOW_OUT;
+ GtkBorder border;
+ gint toggle_size;
+
+ gtk_style_context_get_padding(context, flags, &border);
+ gtk_widget_style_get(widget, "shadow-type", &shadow_type, NULL);
+
+ remaining_space.x = (border_width + border.left);
+ remaining_space.y = (border_width + border.top);
+ remaining_space.width = allocation->width -
+ 2 * border_width - border.left - border.right;
+ remaining_space.height = allocation->height -
+ 2 * border_width - border.top - border.bottom;
+
+ if (shadow_type != GTK_SHADOW_NONE)
+ {
+ gtk_style_context_get_border(context, flags, &border);
+
+ remaining_space.x += border.left;
+ remaining_space.y += border.top;
+ remaining_space.width -= border.left + border.right;
+ remaining_space.height -= border.top + border.bottom;
+ }
+
+ GtkRequestedSize* request = requested_sizes;
+ int size = remaining_space.width;
+ gboolean ltr = (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_LTR) == (pack_direction == GTK_PACK_DIRECTION_LTR);
+
+ for(item = shell_children; item; item = g_list_next(item))
+ {
+ if (!gtk_widget_get_visible(item->data))
+ continue;
+
+ request->data = item->data;
+ gtk_widget_get_preferred_width_for_height(item->data, remaining_space.height,
+ &request->minimum_size,
+ &request->natural_size);
+ gtk_menu_item_toggle_size_request(GTK_MENU_ITEM(item->data),
+ &toggle_size);
+ request->minimum_size += toggle_size;
+ request->natural_size += toggle_size;
+
+ gtk_menu_item_toggle_size_allocate(GTK_MENU_ITEM(item->data), toggle_size);
+
+ size -= request->minimum_size;
+ request++;
+ }
+
+ size = gtk_distribute_natural_allocation(size, visible_count, requested_sizes);
+
+ /* Distribution extra space for widgets with expand=True */
+ if(size > 0 && expand_nums)
+ {
+ expand_nums = g_list_sort_with_data(expand_nums, (GCompareDataFunc)sort_minimal_size,
+ requested_sizes);
+ GList* first_item = expand_nums;
+ gint needed_size = -1;
+ gint max_size = requested_sizes[GPOINTER_TO_INT(first_item->data)].natural_size;
+ gint total_needed_size = 0;
+
+
+ /* Free space that all widgets need to have the same (max_size) width
+ * [___max_width___][widget ][widget____ ]
+ * total_needed_size := [] + [ ] + [ ]
+ * total_needed_size = [ ]
+ */
+ for(item = g_list_next(expand_nums); item; item = g_list_next(item))
+ total_needed_size += max_size - requested_sizes[GPOINTER_TO_INT(item->data)].natural_size;
+
+ while(first_item)
+ {
+ if(size >= total_needed_size)
+ {
+ /* total_needed_size is enough for all remaining widgets */
+ needed_size = max_size + (size - total_needed_size)/expand_count;
+ break;
+ }
+ /* Removing current maximal widget from list */
+ total_needed_size -= max_size - requested_sizes[GPOINTER_TO_INT(item->data)].natural_size;
+ first_item = g_list_next(first_item);
+ if(first_item)
+ max_size = requested_sizes[GPOINTER_TO_INT(first_item->data)].natural_size;
+ }
+
+ for(item = first_item; item; item = g_list_next(item))
+ {
+ request = &requested_sizes[GPOINTER_TO_INT(item->data)];
+ gint dsize = needed_size - request->natural_size;
+ if(size < dsize)
+ dsize = size;
+ size -= dsize;
+ request->natural_size += dsize;
+ }
+ }
+
+ gint i;
+ for(i = 0; i < visible_count; i++)
+ {
+ GtkAllocation child_allocation = remaining_space;
+ request = &requested_sizes[i];
+
+ child_allocation.width = request->natural_size;
+ remaining_space.width -= request->natural_size;
+ if (ltr)
+ remaining_space.x += request->natural_size;
+ else
+ child_allocation.x += remaining_space.width;
+ gtk_widget_size_allocate(request->data, &child_allocation);
+ }
+ g_list_free(expand_nums);
+ }
+ g_list_free(shell_children);
+}
+#else
+static gboolean
+widget_get_expand (GtkWidget* widget)
+{
+ return g_object_get_data(G_OBJECT(widget),
+ GREETER_MENU_BAR_EXPAND_PROP) != NULL;
+}
+
+struct RequestedSize
+{
+ GtkWidget* child;
+ GtkRequisition size;
+};
+
+static gint
+sort_minimal_size(gconstpointer a, gconstpointer b, struct RequestedSize* sizes)
+{
+ gint a_size = sizes[GPOINTER_TO_INT(a)].size.width;
+ gint b_size = sizes[GPOINTER_TO_INT(b)].size.width;
+ return a_size == b_size ? 0 : a_size > b_size ? -1 : +1;
+}
+
+static void
+greeter_menu_bar_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
+{
+ GList* item;
+ GList* shell_children;
+ GList* expand_nums = NULL;
+ guint visible_count = 0, expand_count = 0;
+
+ g_return_if_fail (GTK_IS_MENU_BAR (widget));
+ g_return_if_fail (allocation != NULL);
+
+ GtkPackDirection pack_direction = gtk_menu_bar_get_pack_direction(GTK_MENU_BAR(widget));
+ g_return_if_fail(pack_direction == GTK_PACK_DIRECTION_LTR || pack_direction == GTK_PACK_DIRECTION_RTL);
+
+ shell_children = GTK_MENU_SHELL (widget)->children;
+
+ for(item = shell_children; item; item = g_list_next(item))
+ if(gtk_widget_get_visible(item->data))
+ {
+ if(widget_get_expand(item->data))
+ {
+ expand_nums = g_list_prepend(expand_nums, GINT_TO_POINTER(visible_count));
+ expand_count++;
+ }
+ visible_count++;
+ }
+
+ widget->allocation = *allocation;
+ if (gtk_widget_get_realized (widget))
+ gdk_window_move_resize (widget->window,
+ allocation->x, allocation->y,
+ allocation->width, allocation->height);
+
+ if (visible_count)
+ {
+ gint toggle_size, ipadding;
+ GtkTextDirection direction = gtk_widget_get_direction (widget);
+ GtkShadowType shadow_type = GTK_SHADOW_OUT;
+ GtkAllocation remaining_space;
+
+ gtk_widget_style_get (widget, "shadow-type", &shadow_type, NULL);
+ gtk_widget_style_get (widget, "internal-padding", &ipadding, NULL);
+
+ remaining_space.x = (GTK_CONTAINER (widget)->border_width + ipadding);
+ remaining_space.y = (GTK_CONTAINER (widget)->border_width);
+ remaining_space.width = allocation->width - 2 * remaining_space.x;
+ remaining_space.height = allocation->height - 2 * remaining_space.y;
+
+ if (shadow_type != GTK_SHADOW_NONE)
+ {
+ remaining_space.x += widget->style->xthickness;
+ remaining_space.y += widget->style->ythickness;
+ remaining_space.width -= 2 * widget->style->xthickness;
+ remaining_space.height -= 2 * widget->style->ythickness;
+ }
+
+ struct RequestedSize* requested_sizes = g_newa(struct RequestedSize, visible_count);
+ struct RequestedSize* request = requested_sizes;
+ int size = remaining_space.width;
+
+ for(item = shell_children; item; item = g_list_next(item))
+ {
+ if (!gtk_widget_get_visible (item->data))
+ continue;
+ request->child = item->data;
+ gtk_menu_item_toggle_size_request (GTK_MENU_ITEM (request->child), &toggle_size);
+ gtk_menu_item_toggle_size_allocate (GTK_MENU_ITEM (request->child), toggle_size);
+ gtk_widget_get_child_requisition (request->child, &request->size);
+ request->size.width += toggle_size;
+ request->size.height += toggle_size;
+ size -= request->size.width;
+ ++request;
+ }
+
+ if(size > 0 && expand_nums)
+ {
+ expand_nums = g_list_sort_with_data(expand_nums, (GCompareDataFunc)sort_minimal_size,
+ requested_sizes);
+ GList* first_item = expand_nums;
+ gint needed_size = -1;
+ gint max_size = requested_sizes[GPOINTER_TO_INT(first_item->data)].size.width;
+ gint total_needed_size = 0;
+
+ for(item = g_list_next(expand_nums); item; item = g_list_next(item))
+ total_needed_size += max_size - requested_sizes[GPOINTER_TO_INT(item->data)].size.width;
+
+ while(first_item)
+ {
+ if(size >= total_needed_size)
+ {
+ needed_size = max_size + (size - total_needed_size)/expand_count;
+ break;
+ }
+ total_needed_size -= max_size - requested_sizes[GPOINTER_TO_INT(item->data)].size.width;
+ first_item = g_list_next(first_item);
+ if(first_item)
+ max_size = requested_sizes[GPOINTER_TO_INT(first_item->data)].size.width;
+ }
+
+ for(item = first_item; item; item = g_list_next(item))
+ {
+ request = &requested_sizes[GPOINTER_TO_INT(item->data)];
+ gint dsize = needed_size - request->size.width;
+ if(size < dsize)
+ dsize = size;
+ size -= dsize;
+ request->size.width += dsize;
+ }
+ }
+
+ gboolean ltr = (direction == GTK_TEXT_DIR_LTR) == (pack_direction == GTK_PACK_DIRECTION_LTR);
+ GtkAllocation child_allocation;
+ gint i;
+ for(i = 0; i < visible_count; i++)
+ {
+ child_allocation = remaining_space;
+ request = &requested_sizes[i];
+
+ child_allocation.width = request->size.width;
+ remaining_space.width -= request->size.width;
+ if (ltr)
+ remaining_space.x += request->size.width;
+ else
+ child_allocation.x += remaining_space.width;
+ gtk_widget_size_allocate(request->child, &child_allocation);
+ }
+ g_list_free(expand_nums);
+ }
+}
+#endif
diff --git a/src/greetermenubar.h b/src/greetermenubar.h
new file mode 100644
index 0000000..7d356cd
--- /dev/null
+++ b/src/greetermenubar.h
@@ -0,0 +1,37 @@
+#ifndef GREETER_MENU_BAR_H
+#define GREETER_MENU_BAR_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#if !GTK_CHECK_VERSION (3, 0, 0)
+#define GREETER_MENU_BAR_EXPAND_PROP "gtk2-fallback-expand"
+#endif
+
+G_BEGIN_DECLS
+
+#define GREETER_MENU_BAR_TYPE (greeter_menu_bar_get_type())
+#define GREETER_MENU_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GREETER_MENU_BAR_TYPE, GreeterMenuBar))
+#define GREETER_MENU_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GREETER_MENU_BAR_TYPE, GreeterMenuBarClass))
+#define GREETER_IS_MENU_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GREETER_MENU_BAR_TYPE))
+#define GREETER_IS_MENU_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GREETER_MENU_BAR_TYPE))
+
+typedef struct _GreeterMenuBar GreeterMenuBar;
+typedef struct _GreeterMenuBarClass GreeterMenuBarClass;
+
+struct _GreeterMenuBar
+{
+ GtkMenuBar parent_instance;
+};
+
+struct _GreeterMenuBarClass
+{
+ GtkMenuBarClass parent_class;
+};
+
+GType greeter_menu_bar_get_type(void) G_GNUC_CONST;
+GtkWidget *greeter_menu_bar_new(void);
+
+G_END_DECLS
+
+#endif /* GREETER_MENU_BAR_H */
diff --git a/src/lightdm-gtk-greeter.c b/src/lightdm-gtk-greeter.c
index 26a2668..4a54f3b 100644
--- a/src/lightdm-gtk-greeter.c
+++ b/src/lightdm-gtk-greeter.c
@@ -55,7 +55,8 @@
#include <lightdm.h>
-#include <src/lightdm-gtk-greeter-ui.h>
+#include "src/greetermenubar.h"
+#include "src/lightdm-gtk-greeter-ui.h"
#if GTK_CHECK_VERSION (3, 0, 0)
#include <src/lightdm-gtk-greeter-css-fallback.h>
@@ -73,11 +74,11 @@ static GdkPixbuf *background_pixbuf = NULL;
/* Panel Widgets */
static GtkWindow *panel_window;
-static GtkWidget *clock_label;
-static GtkWidget *menubar, *power_menuitem, *session_menuitem, *language_menuitem, *a11y_menuitem,
+static GtkWidget *menubar;
+static GtkWidget *power_menuitem, *session_menuitem, *language_menuitem, *a11y_menuitem,
*layout_menuitem, *session_badge;
static GtkWidget *suspend_menuitem, *hibernate_menuitem, *restart_menuitem, *shutdown_menuitem;
-static GtkWidget *keyboard_menuitem;
+static GtkWidget *keyboard_menuitem, *clock_menuitem, *clock_label, *host_menuitem;
static GtkMenu *session_menu, *language_menu, *layout_menu;
/* Login Window Widgets */
@@ -164,6 +165,35 @@ static const gchar *LAYOUT_DATA_NAME = "layout-name";
static XklEngine *xkl_engine;
#endif
+typedef enum
+{
+ PANEL_ITEM_INDICATOR,
+ PANEL_ITEM_SPACER,
+ PANEL_ITEM_SEPARATOR,
+ PANEL_ITEM_TEXT
+} GreeterPanelItemType;
+
+#if GTK_CHECK_VERSION (3, 0, 0)
+static const gchar *PANEL_ITEM_STYLE = "panel-item";
+static const gchar *PANEL_ITEM_STYLE_HOVERED = "panel-item-hovered";
+
+static const gchar *PANEL_ITEM_STYLES[] =
+{
+ "panel-item-indicator",
+ "panel-item-spacer",
+ "panel-item-separator",
+ "panel-item-text"
+};
+#endif
+
+static const gchar *PANEL_ITEM_DATA_INDEX = "panel-item-data-index";
+
+#ifdef HAVE_LIBINDICATOR
+static const gchar *INDICATOR_ITEM_DATA_OBJECT = "indicator-item-data-object";
+static const gchar *INDICATOR_ITEM_DATA_ENTRY = "indicator-item-data-entry";
+static const gchar *INDICATOR_ITEM_DATA_BOX = "indicator-item-data-box";
+static const gchar *INDICATOR_DATA_MENUITEMS = "indicator-data-menuitems";
+#endif
static void
pam_message_finalize (PAMConversationMessage *message)
@@ -172,34 +202,60 @@ pam_message_finalize (PAMConversationMessage *message)
g_free (message);
}
+#if GTK_CHECK_VERSION (3, 0, 0)
+static gboolean
+panel_item_enter_notify_cb (GtkWidget *widget, GdkEvent *event, gpointer enter)
+{
+ GtkStyleContext *context = gtk_widget_get_style_context (widget);
+ if (GPOINTER_TO_INT (enter))
+ gtk_style_context_add_class (context, PANEL_ITEM_STYLE_HOVERED);
+ else
+ gtk_style_context_remove_class (context, PANEL_ITEM_STYLE_HOVERED);
+ return FALSE;
+}
+#endif
+
static void
-add_indicator_to_panel (GtkWidget *indicator_item, gint index)
+panel_add_item (GtkWidget *widget, gint index, GreeterPanelItemType item_type)
{
gint insert_pos = 0;
GList* items = gtk_container_get_children (GTK_CONTAINER (menubar));
GList* item;
for (item = items; item; item = item->next)
{
- if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item->data), "indicator-custom-index-data")) < index)
+ if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item->data), PANEL_ITEM_DATA_INDEX)) < index)
break;
insert_pos++;
}
g_list_free (items);
- gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), GTK_WIDGET (indicator_item), insert_pos);
+ #if GTK_CHECK_VERSION (3, 0, 0)
+ gtk_style_context_add_class (gtk_widget_get_style_context (widget), PANEL_ITEM_STYLE);
+ gtk_style_context_add_class (gtk_widget_get_style_context (widget), PANEL_ITEM_STYLES[item_type]);
+ if (item_type == PANEL_ITEM_INDICATOR)
+ {
+ g_signal_connect (G_OBJECT (widget), "enter-notify-event",
+ G_CALLBACK (panel_item_enter_notify_cb), GINT_TO_POINTER(TRUE));
+ g_signal_connect (G_OBJECT (widget), "leave-notify-event",
+ G_CALLBACK (panel_item_enter_notify_cb), GINT_TO_POINTER(FALSE));
+ }
+ #endif
+
+ gtk_widget_show (widget);
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), widget, insert_pos);
}
#ifdef HAVE_LIBINDICATOR
static gboolean
-entry_scrolled (GtkWidget *menuitem, GdkEventScroll *event, gpointer data)
+indicator_entry_scrolled_cb (GtkWidget *menuitem, GdkEventScroll *event, gpointer data)
{
IndicatorObject *io;
IndicatorObjectEntry *entry;
g_return_val_if_fail (GTK_IS_WIDGET (menuitem), FALSE);
- io = g_object_get_data (G_OBJECT (menuitem), "indicator-custom-object-data");
- entry = g_object_get_data (G_OBJECT (menuitem), "indicator-custom-entry-data");
+ io = g_object_get_data (G_OBJECT (menuitem), INDICATOR_ITEM_DATA_OBJECT);
+ entry = g_object_get_data (G_OBJECT (menuitem), INDICATOR_ITEM_DATA_ENTRY);
g_return_val_if_fail (INDICATOR_IS_OBJECT (io), FALSE);
@@ -210,15 +266,15 @@ entry_scrolled (GtkWidget *menuitem, GdkEventScroll *event, gpointer data)
}
static void
-entry_activated (GtkWidget *widget, gpointer user_data)
+indicator_entry_activated_cb (GtkWidget *widget, gpointer user_data)
{
IndicatorObject *io;
IndicatorObjectEntry *entry;
g_return_if_fail (GTK_IS_WIDGET (widget));
- io = g_object_get_data (G_OBJECT (widget), "indicator-custom-object-data");
- entry = g_object_get_data (G_OBJECT (widget), "indicator-custom-entry-data");
+ io = g_object_get_data (G_OBJECT (widget), INDICATOR_ITEM_DATA_OBJECT);
+ entry = g_object_get_data (G_OBJECT (widget), INDICATOR_ITEM_DATA_ENTRY);
g_return_if_fail (INDICATOR_IS_OBJECT (io));
@@ -226,10 +282,10 @@ entry_activated (GtkWidget *widget, gpointer user_data)
}
static GtkWidget*
-create_menuitem (IndicatorObject *io, IndicatorObjectEntry *entry, GtkWidget *menubar)
+indicator_entry_create_menuitem (IndicatorObject *io, IndicatorObjectEntry *entry, GtkWidget *menubar)
{
GtkWidget *box, *menuitem;
- gint index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (io), "indicator-custom-index-data"));
+ gint index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (io), PANEL_ITEM_DATA_INDEX));
#if GTK_CHECK_VERSION (3, 0, 0)
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
@@ -240,13 +296,13 @@ create_menuitem (IndicatorObject *io, IndicatorObjectEntry *entry, GtkWidget *me
gtk_widget_add_events(GTK_WIDGET(menuitem), GDK_SCROLL_MASK);
- g_object_set_data (G_OBJECT (menuitem), "indicator-custom-box-data", box);
- g_object_set_data (G_OBJECT (menuitem), "indicator-custom-object-data", io);
- g_object_set_data (G_OBJECT (menuitem), "indicator-custom-entry-data", entry);
- g_object_set_data (G_OBJECT (menuitem), "indicator-custom-index-data", GINT_TO_POINTER (index));
+ g_object_set_data (G_OBJECT (menuitem), INDICATOR_ITEM_DATA_BOX, box);
+ g_object_set_data (G_OBJECT (menuitem), INDICATOR_ITEM_DATA_OBJECT, io);
+ g_object_set_data (G_OBJECT (menuitem), INDICATOR_ITEM_DATA_ENTRY, entry);
+ g_object_set_data (G_OBJECT (menuitem), PANEL_ITEM_DATA_INDEX, GINT_TO_POINTER (index));
- g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (entry_activated), NULL);
- g_signal_connect (G_OBJECT (menuitem), "scroll-event", G_CALLBACK (entry_scrolled), NULL);
+ g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (indicator_entry_activated_cb), NULL);
+ g_signal_connect (G_OBJECT (menuitem), "scroll-event", G_CALLBACK (indicator_entry_scrolled_cb), NULL);
if (entry->image)
gtk_box_pack_start (GTK_BOX(box), GTK_WIDGET(entry->image), FALSE, FALSE, 1);
@@ -259,24 +315,24 @@ create_menuitem (IndicatorObject *io, IndicatorObjectEntry *entry, GtkWidget *me
gtk_container_add (GTK_CONTAINER (menuitem), box);
gtk_widget_show (box);
- add_indicator_to_panel (menuitem, index);
+ panel_add_item(menuitem, index, PANEL_ITEM_INDICATOR);
return menuitem;
}
static void
-entry_added (IndicatorObject *io, IndicatorObjectEntry *entry, gpointer user_data)
+indicator_entry_added_cb (IndicatorObject *io, IndicatorObjectEntry *entry, gpointer user_data)
{
GHashTable *menuitem_lookup;
GtkWidget *menuitem;
/* if the menuitem doesn't already exist, create it now */
- menuitem_lookup = g_object_get_data (G_OBJECT (io), "indicator-custom-menuitems-data");
+ menuitem_lookup = g_object_get_data (G_OBJECT (io), INDICATOR_DATA_MENUITEMS);
g_return_if_fail (menuitem_lookup);
menuitem = g_hash_table_lookup (menuitem_lookup, entry);
if (!GTK_IS_WIDGET (menuitem))
{
- menuitem = create_menuitem (io, entry, GTK_WIDGET (user_data));
+ menuitem = indicator_entry_create_menuitem (io, entry, GTK_WIDGET (user_data));
g_hash_table_insert (menuitem_lookup, entry, menuitem);
}
@@ -284,22 +340,22 @@ entry_added (IndicatorObject *io, IndicatorObjectEntry *entry, gpointer user_dat
}
static void
-entry_removed_cb (GtkWidget *widget, gpointer userdata)
+remove_indicator_entry_cb (GtkWidget *widget, gpointer userdata)
{
IndicatorObject *io;
GHashTable *menuitem_lookup;
GtkWidget *menuitem;
gpointer entry;
- io = g_object_get_data (G_OBJECT (widget), "indicator-custom-object-data");
+ io = g_object_get_data (G_OBJECT (widget), INDICATOR_ITEM_DATA_OBJECT);
if (!INDICATOR_IS_OBJECT (io))
return;
- entry = g_object_get_data (G_OBJECT (widget), "indicator-custom-entry-data");
+ entry = g_object_get_data (G_OBJECT (widget), INDICATOR_ITEM_DATA_ENTRY);
if (entry != userdata)
return;
- menuitem_lookup = g_object_get_data (G_OBJECT (io), "indicator-custom-menuitems-data");
+ menuitem_lookup = g_object_get_data (G_OBJECT (io), INDICATOR_DATA_MENUITEMS);
g_return_if_fail (menuitem_lookup);
menuitem = g_hash_table_lookup (menuitem_lookup, entry);
if (GTK_IS_WIDGET (menuitem))
@@ -309,13 +365,13 @@ entry_removed_cb (GtkWidget *widget, gpointer userdata)
}
static void
-entry_removed (IndicatorObject *io, IndicatorObjectEntry *entry, gpointer user_data)
+indicator_entry_removed_cb (IndicatorObject *io, IndicatorObjectEntry *entry, gpointer user_data)
{
- gtk_container_foreach (GTK_CONTAINER (user_data), entry_removed_cb, entry);
+ gtk_container_foreach (GTK_CONTAINER (user_data), remove_indicator_entry_cb, entry);
}
static void
-menu_show (IndicatorObject *io, IndicatorObjectEntry *entry, guint32 timestamp, gpointer user_data)
+indicator_menu_show_cb (IndicatorObject *io, IndicatorObjectEntry *entry, guint32 timestamp, gpointer user_data)
{
IndicatorObjectEntry *entrydata;
GtkWidget *menuitem;
@@ -403,9 +459,14 @@ init_indicators (GKeyFile* config)
GHashTable *builtin_items = NULL;
GHashTableIter iter;
gpointer iter_value;
+ #ifdef HAVE_LIBINDICATOR
gboolean inited = FALSE;
+ #endif
gboolean fallback = FALSE;
+ const gchar *DEFAULT_LAYOUT[] = {"~host", "~spacer", "~clock", "~spacer",
+ "~session", "~language", "~a11y", "~power", NULL};
+
#ifdef START_INDICATOR_SERVICES
GError *error = NULL;
gchar *AT_SPI_CMD[] = {"/usr/lib/at-spi2-core/at-spi-bus-launcher", "--launch-immediately", NULL};
@@ -423,28 +484,67 @@ init_indicators (GKeyFile* config)
fallback = TRUE;
}
- if (names && !fallback)
+ if (!names || fallback)
{
- builtin_items = g_hash_table_new (g_str_hash, g_str_equal);
+ names = (gchar**)DEFAULT_LAYOUT;
+ length = g_strv_length (names);
+ }
- g_hash_table_insert (builtin_items, "~power", power_menuitem);
- g_hash_table_insert (builtin_items, "~session", session_menuitem);
- g_hash_table_insert (builtin_items, "~language", language_menuitem);
- g_hash_table_insert (builtin_items, "~a11y", a11y_menuitem);
- g_hash_table_insert (builtin_items, "~layout", layout_menuitem);
+ builtin_items = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_iter_init (&iter, builtin_items);
- while (g_hash_table_iter_next (&iter, NULL, &iter_value))
- gtk_container_remove (GTK_CONTAINER (menubar), iter_value);
- }
+ g_hash_table_insert (builtin_items, "~power", power_menuitem);
+ g_hash_table_insert (builtin_items, "~session", session_menuitem);
+ g_hash_table_insert (builtin_items, "~language", language_menuitem);
+ g_hash_table_insert (builtin_items, "~a11y", a11y_menuitem);
+ g_hash_table_insert (builtin_items, "~layout", layout_menuitem);
+ g_hash_table_insert (builtin_items, "~host", host_menuitem);
+ g_hash_table_insert (builtin_items, "~clock", clock_menuitem);
+
+ g_hash_table_iter_init (&iter, builtin_items);
+ while (g_hash_table_iter_next (&iter, NULL, &iter_value))
+ gtk_container_remove (GTK_CONTAINER (menubar), iter_value);
for (i = 0; i < length; ++i)
{
- if (names[i][0] == '~' && g_hash_table_lookup_extended (builtin_items, names[i], NULL, &iter_value))
+ if (names[i][0] == '~')
{ /* Built-in indicators */
- g_object_set_data (G_OBJECT (iter_value), "indicator-custom-index-data", GINT_TO_POINTER (i));
- add_indicator_to_panel (iter_value, i);
- g_hash_table_remove (builtin_items, (gconstpointer)names[i]);
+ GreeterPanelItemType item_type = PANEL_ITEM_INDICATOR;
+ if (g_hash_table_lookup_extended (builtin_items, names[i], NULL, &iter_value))
+ g_hash_table_remove (builtin_items, (gconstpointer)names[i]);
+ else if (g_strcmp0 (names[i], "~separator") == 0)
+ {
+ #if GTK_CHECK_VERSION (3, 0, 0)
+ GtkWidget *separator = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
+ #else
+ GtkWidget *separator = gtk_vseparator_new ();
+ #endif
+ item_type = PANEL_ITEM_SEPARATOR;
+ iter_value = gtk_separator_menu_item_new ();
+ gtk_widget_show (separator);
+ gtk_container_add (iter_value, separator);
+ }
+ else if (g_strcmp0 (names[i], "~spacer") == 0)
+ {
+ item_type = PANEL_ITEM_SPACER;
+ iter_value = gtk_separator_menu_item_new ();
+ gtk_menu_item_set_label (iter_value, "");
+ #if GTK_CHECK_VERSION (3, 0, 0)
+ gtk_widget_set_hexpand (iter_value, TRUE);
+ #else
+ g_object_set_data(G_OBJECT(iter_value), GREETER_MENU_BAR_EXPAND_PROP, "1");
+ #endif
+ }
+ else if (names[i][1] == '~')
+ {
+ item_type = PANEL_ITEM_TEXT;
+ iter_value = gtk_separator_menu_item_new ();
+ gtk_menu_item_set_label (iter_value, &names[i][2]);
+ }
+ else
+ continue;
+
+ g_object_set_data (G_OBJECT (iter_value), PANEL_ITEM_DATA_INDEX, GINT_TO_POINTER (i));
+ panel_add_item (iter_value, i, item_type);
continue;
}
@@ -497,21 +597,21 @@ init_indicators (GKeyFile* config)
GList *entries, *lp;
/* used to store/fetch menu entries */
- g_object_set_data_full (G_OBJECT (io), "indicator-custom-menuitems-data",
+ g_object_set_data_full (G_OBJECT (io), INDICATOR_DATA_MENUITEMS,
g_hash_table_new (g_direct_hash, g_direct_equal),
(GDestroyNotify) g_hash_table_destroy);
- g_object_set_data (G_OBJECT (io), "indicator-custom-index-data", GINT_TO_POINTER (i));
+ g_object_set_data (G_OBJECT (io), PANEL_ITEM_DATA_INDEX, GINT_TO_POINTER (i));
g_signal_connect (G_OBJECT (io), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,
- G_CALLBACK (entry_added), menubar);
+ G_CALLBACK (indicator_entry_added_cb), menubar);
g_signal_connect (G_OBJECT (io), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED,
- G_CALLBACK (entry_removed), menubar);
+ G_CALLBACK (indicator_entry_removed_cb), menubar);
g_signal_connect (G_OBJECT (io), INDICATOR_OBJECT_SIGNAL_MENU_SHOW,
- G_CALLBACK (menu_show), menubar);
+ G_CALLBACK (indicator_menu_show_cb), menubar);
entries = indicator_object_get_entries (io);
for (lp = entries; lp; lp = g_list_next (lp))
- entry_added (io, lp->data, menubar);
+ indicator_entry_added_cb (io, lp->data, menubar);
g_list_free (entries);
}
else
@@ -522,7 +622,7 @@ init_indicators (GKeyFile* config)
g_free (path);
#endif
}
- if (names)
+ if (names && names != (gchar**)DEFAULT_LAYOUT)
g_strfreev (names);
if (builtin_items)
@@ -1691,9 +1791,6 @@ a11y_font_cb (GtkCheckMenuItem *item)
gchar *font_name, **tokens;
guint length;
- /* Hide the clock since indicators are about to eat the screen. */
- gtk_widget_hide(GTK_WIDGET(clock_label));
-
g_object_get (gtk_settings_get_default (), "gtk-font-name", &font_name, NULL);
tokens = g_strsplit (font_name, " ", -1);
length = g_strv_length (tokens);
@@ -1715,8 +1812,6 @@ a11y_font_cb (GtkCheckMenuItem *item)
else
{
g_object_set (gtk_settings_get_default (), "gtk-font-name", default_font_name, NULL);
- /* Show the clock as needed */
- gtk_widget_show_all(GTK_WIDGET(clock_label));
}
}
@@ -2166,8 +2261,8 @@ clock_timeout_thread (void)
strftime(time_str, 50, clock_format, timeinfo);
markup = g_markup_printf_escaped("<b>%s</b>", time_str);
- if (g_strcmp0(markup, gtk_label_get_label(GTK_LABEL(clock_label))) != 0)
- gtk_label_set_markup( GTK_LABEL(clock_label), markup );
+ if (g_strcmp0(markup, gtk_label_get_label (GTK_LABEL (clock_label))) != 0)
+ gtk_label_set_markup (GTK_LABEL (clock_label), markup);
g_free(markup);
return TRUE;
@@ -2646,11 +2741,6 @@ main (int argc, char **argv)
gtk_style_context_add_class(GTK_STYLE_CONTEXT(gtk_widget_get_style_context(GTK_WIDGET(panel_window))), GTK_STYLE_CLASS_MENUBAR);
g_signal_connect (G_OBJECT (panel_window), "draw", G_CALLBACK (background_window_draw), NULL);
#endif
- gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "hostname_label")), lightdm_get_hostname ());
- session_menu = GTK_MENU(gtk_builder_get_object (builder, "session_menu"));
- language_menu = GTK_MENU(gtk_builder_get_object (builder, "language_menu"));
- layout_menu = GTK_MENU(gtk_builder_get_object (builder, "layout_menu"));
- clock_label = GTK_WIDGET(gtk_builder_get_object (builder, "clock_label"));
menubar = GTK_WIDGET (gtk_builder_get_object (builder, "menubar"));
/* Login window */
@@ -2704,11 +2794,16 @@ main (int argc, char **argv)
/* Indicators */
session_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "session_menuitem"));
+ session_menu = GTK_MENU(gtk_builder_get_object (builder, "session_menu"));
language_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "language_menuitem"));
+ language_menu = GTK_MENU(gtk_builder_get_object (builder, "language_menu"));
a11y_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "a11y_menuitem"));
power_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "power_menuitem"));
layout_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "layout_menuitem"));
+ layout_menu = GTK_MENU(gtk_builder_get_object (builder, "layout_menu"));
keyboard_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "keyboard_menuitem"));
+ clock_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "clock_menuitem"));
+ host_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "host_menuitem"));
gtk_accel_map_add_entry ("<Login>/a11y/font", GDK_KEY_F1, 0);
gtk_accel_map_add_entry ("<Login>/a11y/contrast", GDK_KEY_F2, 0);
@@ -2738,15 +2833,6 @@ main (int argc, char **argv)
g_free (value);
}
- /* Clock */
- gtk_widget_set_no_show_all(GTK_WIDGET(clock_label),
- !g_key_file_get_boolean (config, "greeter", "show-clock", NULL));
- gtk_widget_show_all(GTK_WIDGET(clock_label));
- clock_format = g_key_file_get_value (config, "greeter", "clock-format", NULL);
- if (!clock_format)
- clock_format = "%a, %H:%M";
- clock_timeout_thread();
-
/* Session menu */
if (gtk_widget_get_visible (session_menuitem))
{
@@ -2814,7 +2900,7 @@ main (int argc, char **argv)
}
set_language (NULL);
}
-
+
/* a11y menu */
if (gtk_widget_get_visible (a11y_menuitem))
{
@@ -2882,6 +2968,22 @@ main (int argc, char **argv)
update_layouts_menu_state ();
}
+ /* Host label */
+ if (gtk_widget_get_visible (host_menuitem))
+ gtk_menu_item_set_label (GTK_MENU_ITEM (host_menuitem), lightdm_get_hostname ());
+
+ /* Clock label */
+ if (gtk_widget_get_visible (clock_menuitem))
+ {
+ gtk_menu_item_set_label (GTK_MENU_ITEM (clock_menuitem), "");
+ clock_label = gtk_bin_get_child (GTK_BIN (clock_menuitem));
+ clock_format = g_key_file_get_value (config, "greeter", "clock-format", NULL);
+ if (!clock_format)
+ clock_format = "%a, %H:%M";
+ clock_timeout_thread ();
+ gdk_threads_add_timeout (1000, (GSourceFunc) clock_timeout_thread, NULL);
+ }
+
#if GTK_CHECK_VERSION (3, 0, 0)
/* A bit of CSS */
css_provider = gtk_css_provider_new ();
@@ -3011,7 +3113,6 @@ main (int argc, char **argv)
}
gtk_widget_set_sensitive (keyboard_menuitem, a11y_keyboard_command != NULL);
gtk_widget_set_visible (keyboard_menuitem, a11y_keyboard_command != NULL);
- gdk_threads_add_timeout (1000, (GSourceFunc) clock_timeout_thread, NULL);
/* focus fix (source: unity-greeter) */
GdkWindow* root_window = gdk_get_default_root_window ();