Commit cb3852df authored by Frederic Peters's avatar Frederic Peters Committed by Michael Catanzaro

chat: use a single window, with tabs

parent d1176783
......@@ -58,8 +58,7 @@ bin_PROGRAMS = \
libexec_PROGRAMS = \
empathy-auth-client \
empathy-call \
empathy-chat
empathy-call
empathy_accounts_SOURCES = \
empathy-accounts.c empathy-accounts.h \
......@@ -92,6 +91,7 @@ empathy_chat_SOURCES = \
empathy-chat-window.c empathy-chat-window.h \
empathy-invite-participant-dialog.c empathy-invite-participant-dialog.h \
empathy-chat.c \
polari-fixed-size-frame.c polari-fixed-size-frame.h \
$(NULL)
nodist_empathy_chat_SOURCES = \
......@@ -151,6 +151,7 @@ empathy_handwritten_source = \
empathy-preferences.c empathy-preferences.h \
empathy-status-icon.c empathy-status-icon.h \
empathy-chat-manager.c empathy-chat-manager.h \
polari-fixed-size-frame.c polari-fixed-size-frame.h \
empathy.c
empathy_SOURCES = \
......
......@@ -45,6 +45,7 @@
#include "empathy-sound-manager.h"
#include "empathy-ui-utils.h"
#include "empathy-utils.h"
#include "empathy-new-message-dialog.h"
#define DEBUG_FLAG EMPATHY_DEBUG_CHAT
#include "empathy-debug.h"
......@@ -170,7 +171,7 @@ static void empathy_chat_window_get_nb_chats (EmpathyChatWindow *self,
guint *nb_rooms,
guint *nb_private);
G_DEFINE_TYPE (EmpathyChatWindow, empathy_chat_window, GTK_TYPE_WINDOW)
G_DEFINE_TYPE (EmpathyChatWindow, empathy_chat_window, GTK_TYPE_BIN)
static void
chat_window_accel_cb (GtkAccelGroup *accelgroup,
......@@ -313,7 +314,7 @@ confirm_close (EmpathyChatWindow *self,
}
dialog = gtk_message_dialog_new (
GTK_WINDOW (self),
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_WARNING,
GTK_BUTTONS_CANCEL,
......@@ -603,6 +604,9 @@ chat_window_contact_menu_update (EmpathyChatWindow *self)
{
GtkWidget *menu, *submenu, *orig_submenu;
if (self->priv->current_chat == NULL)
return;
if (self->priv->updating_menu)
return;
self->priv->updating_menu = TRUE;
......@@ -731,7 +735,7 @@ chat_window_title_update (EmpathyChatWindow *self)
gchar *name;
name = get_window_title_name (self);
gtk_window_set_title (GTK_WINDOW (self), name);
//gtk_window_set_title (GTK_WINDOW (self), name);
g_free (name);
}
......@@ -749,8 +753,8 @@ chat_window_icon_update (EmpathyChatWindow *self,
/* Update window icon */
if (new_messages)
{
gtk_window_set_icon_name (GTK_WINDOW (self),
EMPATHY_IMAGE_MESSAGE);
//gtk_window_set_icon_name (GTK_WINDOW (self),
// EMPATHY_IMAGE_MESSAGE);
}
else
{
......@@ -762,14 +766,14 @@ chat_window_icon_update (EmpathyChatWindow *self,
remote_contact = empathy_chat_get_remote_contact (self->priv->current_chat);
icon = empathy_pixbuf_avatar_from_contact_scaled (remote_contact,
0, 0);
gtk_window_set_icon (GTK_WINDOW (self), icon);
//gtk_window_set_icon (GTK_WINDOW (self), icon);
if (icon != NULL)
g_object_unref (icon);
}
else
{
gtk_window_set_icon_name (GTK_WINDOW (self), NULL);
//gtk_window_set_icon_name (GTK_WINDOW (self), NULL);
}
}
}
......@@ -1258,7 +1262,7 @@ chat_window_invite_participant_activate_cb (GtkAction *action,
tp_chat = empathy_chat_get_tp_chat (self->priv->current_chat);
dialog = empathy_invite_participant_dialog_new (
GTK_WINDOW (self), tp_chat);
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))), tp_chat);
gtk_widget_show (dialog);
......@@ -1447,6 +1451,19 @@ chat_window_tabs_previous_activate_cb (GtkAction *action,
gtk_notebook_prev_page (GTK_NOTEBOOK (self->priv->notebook));
}
void
empathy_chat_window_next_tab (EmpathyChatWindow *self)
{
chat_window_tabs_next_activate_cb (NULL, self);
}
void
empathy_chat_window_prev_tab (EmpathyChatWindow *self)
{
chat_window_tabs_previous_activate_cb (NULL, self);
}
static void
chat_window_tabs_undo_close_tab_activate_cb (GtkAction *action,
EmpathyChatWindow *self)
......@@ -1491,14 +1508,10 @@ chat_window_tabs_right_activate_cb (GtkAction *action,
chat_window_menu_context_update (self, num_pages);
}
static EmpathyChatWindow *
EmpathyChatWindow *
empathy_chat_window_new (void)
{
return g_object_new (EMPATHY_TYPE_CHAT_WINDOW,
"default-width", 580,
"default-height", 480,
"title", _("Chat"),
"role", "chat",
NULL);
}
......@@ -1528,7 +1541,7 @@ static void
chat_window_help_about_activate_cb (GtkAction *action,
EmpathyChatWindow *self)
{
empathy_about_dialog_new (GTK_WINDOW (self));
empathy_about_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))));
}
static gboolean
......@@ -1575,7 +1588,7 @@ static void
chat_window_set_urgency_hint (EmpathyChatWindow *self,
gboolean urgent)
{
gtk_window_set_urgency_hint (GTK_WINDOW (self), urgent);
//gtk_window_set_urgency_hint (GTK_WINDOW (self), urgent);
}
static void
......@@ -1678,7 +1691,7 @@ empathy_chat_window_has_focus (EmpathyChatWindow *self)
g_return_val_if_fail (EMPATHY_IS_CHAT_WINDOW (self), FALSE);
g_object_get (self, "has-toplevel-focus", &has_focus, NULL);
g_object_get ( gtk_widget_get_toplevel (GTK_WIDGET (self)), "has-toplevel-focus", &has_focus, NULL);
return has_focus;
}
......@@ -1849,7 +1862,7 @@ notebook_create_window_cb (GtkNotebook *source,
empathy_chat_window_move_chat (window, new_window, chat);
gtk_widget_show (GTK_WIDGET (new_window));
gtk_window_move (GTK_WINDOW (new_window), x, y);
//gtk_window_move (GTK_WINDOW (new_window), x, y);
return NULL;
}
......@@ -1975,6 +1988,9 @@ chat_window_focus_in_event_cb (GtkWidget *widget,
GdkEvent *event,
EmpathyChatWindow *self)
{
if (self->priv->current_chat == NULL) {
return FALSE;
}
empathy_chat_messages_read (self->priv->current_chat);
chat_window_set_urgency_hint (self, FALSE);
......@@ -2406,6 +2422,17 @@ empathy_chat_window_class_init (EmpathyChatWindowClass *klass)
g_type_class_add_private (object_class, sizeof (EmpathyChatWindowPriv));
}
static void
chat_window_chat_new_message_cb (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
EmpathyChatWindow *self = user_data;
//empathy_new_message_dialog_show (GTK_WINDOW (self));
}
static void
empathy_chat_window_init (EmpathyChatWindow *self)
{
......@@ -2416,6 +2443,7 @@ empathy_chat_window_init (EmpathyChatWindow *self)
GtkWidget *submenu;
guint i;
GtkWidget *chat_vbox;
GtkWidget *main_box;
gchar *filename;
EmpathySmileyManager *smiley_manager;
......@@ -2425,6 +2453,7 @@ empathy_chat_window_init (EmpathyChatWindow *self)
filename = empathy_file_lookup ("empathy-chat-window.ui", "src");
gui = tpaw_builder_get_file (filename,
"chat_vbox", &chat_vbox,
"main_box", &main_box,
"ui_manager", &self->priv->ui_manager,
"menu_conv_insert_smiley", &self->priv->menu_conv_insert_smiley,
"menu_conv_favorite", &self->priv->menu_conv_favorite,
......@@ -2480,11 +2509,12 @@ empathy_chat_window_init (EmpathyChatWindow *self)
self->priv->sound_mgr = empathy_sound_manager_dup_singleton ();
self->priv->notebook = gtk_notebook_new ();
//gtk_notebook_set_show_tabs (GTK_NOTEBOOK (self->priv->notebook), FALSE);
g_signal_connect (self->priv->notebook, "create-window",
G_CALLBACK (notebook_create_window_cb), self);
gtk_container_add (GTK_CONTAINER (self), chat_vbox);
gtk_container_add (GTK_CONTAINER (self), main_box);
gtk_notebook_set_group_name (GTK_NOTEBOOK (self->priv->notebook),
"EmpathyChatWindow");
......@@ -2493,9 +2523,10 @@ empathy_chat_window_init (EmpathyChatWindow *self)
gtk_box_pack_start (GTK_BOX (chat_vbox), self->priv->notebook, TRUE, TRUE, 0);
gtk_widget_show (self->priv->notebook);
#if 0 /* no top level window yet at this point */
/* Set up accels */
accel_group = gtk_accel_group_new ();
gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
gtk_window_add_accel_group (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))), accel_group);
for (i = 0; i < G_N_ELEMENTS (tab_accel_keys); i++)
{
......@@ -2507,6 +2538,7 @@ empathy_chat_window_init (EmpathyChatWindow *self)
}
g_object_unref (accel_group);
#endif
/* Set up drag target lists */
self->priv->contact_targets = gtk_target_list_new (drag_types_dest_contact,
......@@ -2590,6 +2622,7 @@ empathy_chat_window_get_default (gboolean room)
separate_windows = g_settings_get_boolean (gsettings,
EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS);
separate_windows = FALSE;
g_object_unref (gsettings);
......@@ -2604,6 +2637,7 @@ empathy_chat_window_get_default (gboolean room)
chat_window = l->data;
#if 0
empathy_chat_window_get_nb_chats (chat_window, &nb_rooms, &nb_private);
/* Skip the window if there aren't any rooms in it */
......@@ -2613,6 +2647,7 @@ empathy_chat_window_get_default (gboolean room)
/* Skip the window if there aren't any 1-1 chats in it */
if (!room && nb_private == 0)
continue;
#endif
return chat_window;
}
......@@ -2643,6 +2678,7 @@ empathy_chat_window_add_chat (EmpathyChatWindow *self,
separate_windows = g_settings_get_boolean (self->priv->gsettings_ui,
EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS);
separate_windows = FALSE;
if (empathy_chat_is_room (chat))
name = "room-window";
......@@ -2652,24 +2688,24 @@ empathy_chat_window_add_chat (EmpathyChatWindow *self,
gint x, y;
/* Save current position of the window */
gtk_window_get_position (GTK_WINDOW (self), &x, &y);
//gtk_window_get_position (GTK_WINDOW (self), &x, &y);
/* First bind to the 'generic' name. So new window for which we didn't
* save a geometry yet will have the geometry of the last saved
* window (bgo #601191). */
empathy_geometry_bind (GTK_WINDOW (self), name);
//empathy_geometry_bind (GTK_WINDOW (self), name);
/* Restore previous position of the window so the newly created window
* won't be in the same position as the latest saved window and so
* completely hide it. */
gtk_window_move (GTK_WINDOW (self), x, y);
//gtk_window_move (GTK_WINDOW (self), x, y);
/* Then bind it to the name of the contact/room so we'll save the
* geometry specific to this window */
name = empathy_chat_get_id (chat);
}
empathy_geometry_bind (GTK_WINDOW (self), name);
//empathy_geometry_bind (GTK_WINDOW (self), name);
}
child = GTK_WIDGET (chat);
......@@ -2824,6 +2860,13 @@ empathy_chat_window_present_chat (EmpathyChat *chat,
EmpathyChatWindow *self;
guint32 x_timestamp;
if (chat == NULL) {
/* initial window */
self = empathy_chat_window_new ();
gtk_widget_show (GTK_WIDGET (self));
return self;
}
g_return_val_if_fail (EMPATHY_IS_CHAT (chat), NULL);
self = chat_window_find_chat (chat);
......@@ -2869,7 +2912,7 @@ empathy_chat_window_present_chat (EmpathyChat *chat,
* to our current desktop but move to the window's desktop instead. This is
* more coherent with Shell's 'app is ready' notication which moves the view
* to the app desktop rather than moving the app itself. */
empathy_move_to_window_desktop (GTK_WINDOW (self), x_timestamp);
empathy_move_to_window_desktop (GTK_WINDOW (gtk_widget_get_toplevel(GTK_WIDGET(self))), x_timestamp);
gtk_widget_grab_focus (chat->input_text_view);
return self;
......
......@@ -63,13 +63,13 @@ typedef struct _EmpathyChatWindowPriv EmpathyChatWindowPriv;
struct _EmpathyChatWindow
{
GtkWindow parent;
GtkBin parent;
EmpathyChatWindowPriv *priv;
};
struct _EmpathyChatWindowClass
{
GtkWindowClass parent_class;
GtkBinClass parent_class;
};
GType empathy_chat_window_get_type (void);
......@@ -81,9 +81,14 @@ EmpathyChat * empathy_chat_window_find_chat (TpAccount *account,
EmpathyChatWindow * empathy_chat_window_present_chat (EmpathyChat *chat,
gint64 timestamp);
EmpathyChatWindow * empathy_chat_window_new (void);
EmpathyIndividualManager * empathy_chat_window_get_individual_manager (
EmpathyChatWindow *self);
void empathy_chat_window_next_tab (EmpathyChatWindow *self);
void empathy_chat_window_prev_tab (EmpathyChatWindow *self);
G_END_DECLS
#endif
......@@ -176,6 +176,7 @@
<property name="stock_id">gtk-about</property>
<property name="name">menu_help_about</property>
</object>
<accelerator key="F2" modifiers=""/>
</child>
</object>
</child>
......@@ -213,24 +214,28 @@
</menu>
<menu action="menu_help">
<menuitem action="menu_help_contents"/>
<menuitem action="menu_help_about"/>
</menu>
</menubar>
</ui>
</object>
<object class="GtkBox" id="main_box">
<property name="can_focus">False</property>
<property name="orientation">horizontal</property>
<property name="visible">True</property>
<child>
<object class="GtkVBox" id="chat_vbox">
<property name="visible">True</property>
<child>
<object class="GtkMenuBar" constructor="ui_manager" id="chats_menubar">
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</interface>
......@@ -76,6 +76,8 @@ activate_cb (GApplication *application)
g_assert (chat_mgr == NULL);
chat_mgr = empathy_chat_manager_dup_singleton ();
empathy_chat_window_present_chat(NULL, 0);
g_signal_connect (chat_mgr, "displayed-chats-changed",
G_CALLBACK (displayed_chats_changed_cb), GUINT_TO_POINTER (1));
}
......
......@@ -32,6 +32,7 @@
#include "empathy-accounts-dialog.h"
#include "empathy-call-observer.h"
#include "empathy-chat-manager.h"
#include "empathy-chat-window.h"
#include "empathy-chatroom-manager.h"
#include "empathy-chatrooms-window.h"
#include "empathy-client-factory.h"
......@@ -55,6 +56,8 @@
#include "empathy-roster-model-manager.h"
#include "empathy-roster-view.h"
#include "empathy-status-presets.h"
#include "empathy-theme-manager.h"
#include "empathy-theme-manager.h"
#include "empathy-ui-utils.h"
#include "empathy-utils.h"
......@@ -90,6 +93,8 @@ G_DEFINE_TYPE (EmpathyRosterWindow, empathy_roster_window, GTK_TYPE_APPLICATION_
struct _EmpathyRosterWindowPriv {
EmpathyRosterView *view;
TpAccountManager *account_manager;
EmpathyChatManager *chat_manager;
EmpathyThemeManager *theme_manager;
EmpathyChatroomManager *chatroom_manager;
EmpathyEventManager *event_manager;
EmpathySoundManager *sound_mgr;
......@@ -116,6 +121,7 @@ struct _EmpathyRosterWindowPriv {
GtkWidget *button_add_contact;
GtkWidget *spinner_loading;
GtkWidget *tooltip_widget;
GtkWidget *chat_window;
GMenu *menumodel;
GMenu *rooms_section;
......@@ -1033,6 +1039,8 @@ empathy_roster_window_finalize (GObject *window)
g_object_unref (self->priv->call_observer);
g_object_unref (self->priv->event_manager);
g_object_unref (self->priv->chat_manager);
g_object_unref (self->priv->theme_manager);
g_object_unref (self->priv->chatroom_manager);
g_object_unref (self->priv->gsettings_ui);
......@@ -1540,6 +1548,25 @@ roster_window_help_contents_cb (GSimpleAction *action,
empathy_url_show (GTK_WIDGET (self), "help:empathy");
}
static void
next_tab_cb (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
EmpathyRosterWindow *self = user_data;
empathy_chat_window_next_tab (EMPATHY_CHAT_WINDOW (self->priv->chat_window));
}
static void
prev_tab_cb (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
EmpathyRosterWindow *self = user_data;
empathy_chat_window_prev_tab (EMPATHY_CHAT_WINDOW (self->priv->chat_window));
}
static gboolean
roster_window_throbber_button_press_event_cb (GtkWidget *throbber,
GdkEventButton *event,
......@@ -1898,6 +1925,13 @@ static GActionEntry menubar_entries[] = {
{"help-about", roster_window_help_about_cb},
};
static GActionEntry app_entries[] =
{
{ "tab_next", next_tab_cb, NULL, NULL, NULL },
{ "tab_prev", prev_tab_cb, NULL, NULL, NULL }
};
static void
empathy_roster_window_set_property (GObject *object,
guint property_id,
......@@ -2285,10 +2319,10 @@ empathy_roster_window_init (EmpathyRosterWindow *self)
GtkBuilder *gui;
GtkWidget *sw;
gchar *filename;
GtkWidget *search_vbox;
GtkWidget *header_bar;
GtkWidget *new_conversation_button;
GtkWidget *image;
GtkWidget *chat_vbox;
guint i;
EmpathyRosterModel *model;
......@@ -2313,10 +2347,10 @@ empathy_roster_window_init (EmpathyRosterWindow *self)
filename = empathy_file_lookup ("empathy-roster-window.ui", "src");
gui = tpaw_builder_get_file (filename,
"main_vbox", &self->priv->main_vbox,
"chat_vbox", &chat_vbox,
"balance_vbox", &self->priv->balance_vbox,
"errors_vbox", &self->priv->errors_vbox,
"auth_vbox", &self->priv->auth_vbox,
"search_vbox", &search_vbox,
"presence_toolbar", &self->priv->presence_toolbar,
"notebook", &self->priv->notebook,
"no_entry_label", &self->priv->no_entry_label,
......@@ -2364,6 +2398,10 @@ empathy_roster_window_init (EmpathyRosterWindow *self)
self->priv->status_changed_handlers = g_hash_table_new_full (g_direct_hash,
g_direct_equal, NULL, NULL);
/* set up accelerators */
g_action_map_add_action_entries (G_ACTION_MAP (self),
app_entries, G_N_ELEMENTS (app_entries), self);
/* set up menus */
g_action_map_add_action_entries (G_ACTION_MAP (self),
menubar_entries, G_N_ELEMENTS (menubar_entries), self);
......@@ -2416,6 +2454,7 @@ empathy_roster_window_init (EmpathyRosterWindow *self)
self->priv->view = EMPATHY_ROSTER_VIEW (
empathy_roster_view_new (model));
g_object_unref (model);
gtk_widget_show (GTK_WIDGET (self->priv->view));
......@@ -2454,8 +2493,6 @@ empathy_roster_window_init (EmpathyRosterWindow *self)
GTK_WIDGET (self->priv->view));
empathy_roster_view_set_live_search (self->priv->view,
TPAW_LIVE_SEARCH (self->priv->search_bar));
gtk_box_pack_start (GTK_BOX (search_vbox), self->priv->search_bar,
FALSE, TRUE, 0);
g_signal_connect_swapped (self, "map",
G_CALLBACK (gtk_widget_grab_focus), self->priv->view);
......@@ -2467,9 +2504,16 @@ empathy_roster_window_init (EmpathyRosterWindow *self)
/* Set window size. */
empathy_geometry_bind (GTK_WINDOW (self), GEOMETRY_NAME);
self->priv->chat_window = GTK_WIDGET (empathy_chat_window_new ());
gtk_widget_show (GTK_WIDGET (self->priv->chat_window) );
gtk_box_pack_start (GTK_BOX (chat_vbox), self->priv->chat_window, TRUE, TRUE, 0);
/* Enable event handling */
self->priv->call_observer = empathy_call_observer_dup_singleton ();
self->priv->event_manager = empathy_event_manager_dup_singleton ();
self->priv->chat_manager = empathy_chat_manager_dup_singleton ();
self->priv->theme_manager = empathy_theme_manager_dup_singleton ();
tp_g_signal_connect_object (self->priv->event_manager, "event-added",
G_CALLBACK (roster_window_event_added_cb), self, 0);
......
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<object class="GtkVBox" id="main_vbox">
<property name="visible">True</property>
<object class="GtkBox" id="main_vbox">
<property name="can_focus">False</property>
<property name="border-width">12</property>
<property name="orientation">horizontal</property>
<property name="visible">True</property>
<child>
<object class="GtkHBox" id="presence_toolbar">
<property name="visible">True</property>
<object class="GtkRevealer" id="revealer">
<property name="can_focus">False</property>
<property name="spacing">12</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<property name="hexpand">False</property>
<property name="reveal_child">True</property>
<property name="transition_type">slide-right</property>
<property name="visible">True</property>
<child>
<object class="PolariFixedSizeFrame" id="sidebar_frame">
<property name="hexpand">False</property>
<property name="width">240</property>
<property name="visible">True</property>
<style>
<class name="sidebar"/>
<class name="chat-sidebar"/>
</style>
<child>
<object class="GtkGrid" id="grid0">
<property name="can_focus">False</property>
<property name="hexpand">False</property>
<property name="orientation">vertical</property>
<property name="visible">True</property>
<child>
<object class="GtkVBox" id="balance_vbox">
<property name="can_focus">False</property>
......@@ -57,26 +69,14 @@
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="search_vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkNotebook" id="notebook">
<child>
<object class="GtkNotebook" id="notebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<property name="expand">True</property>
<child>
<object class="GtkScrolledWindow" id="roster_scrolledwindow">
<property name="visible">True</property>
......@@ -251,12 +251,112 @@
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkFrame" id="status_area">
<property name="can_focus">False</property>
<property name="visible">True</property>
<style>
<class name="chat-status-area"/>
</style>
<child>
<object class="GtkGrid" id="status_area_grid0">
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="orientation">horizontal</property>
<property name="vexpand">False</property>
<property name="visible">True</property>
<child>
<object class="GtkGrid" id="status_area_grid1">
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="vexpand">False</property>
<property name="visible">True</property>
<child>
<object class="GtkHBox" id="presence_toolbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">3</property>
<property name="border-width">3</property>
<property name="hexpand">True</property>
</object>
</child>
<child>
<object class="GtkLabel" id="status_area_nickname">
<property name="can_focus">False</property>
<property name="ellipsize">end</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="use_markup">True</property>
<property name="valign">center</property>
<property name="vexpand">True</property>
<property name="visible">False</property>
</object>
</child>
<child>
<object class="GtkGrid" id="status_area_grid2">
<property name="can_focus">False</property>
<property name="column_spacing">3</property>
<property name="hexpand">True</property>
<property name="orientation">horizontal</property>
<property name="vexpand">False</property>
<property name="visible">False</property>
<child>
<object class="GtkImage" id="status_area_presence_icon">
<property name="can_focus">False</property>
<property name="icon_size">1</property>
<property name="visible">False</property>
</object>
</child>
<child>
<object class="GtkLabel" id="status_area_presence_message">
<property name="can_focus">False</property>
<property name="ellipsize">end</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="valign">center</property>
<property name="vexpand">True</property>
<property name="visible">False</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">6</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="chat_vbox">
<property name="visible">True</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>