/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2003-2007 Imendio AB
- * Copyright (C) 2007-2008 Collabora Ltd.
+ * Copyright (C) 2007-2010 Collabora Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
+#include <gdk/gdkx.h>
#include <glib/gi18n.h>
#include <libnotify/notification.h>
#include <libempathy/empathy-contact.h>
#include <libempathy/empathy-message.h>
#include <libempathy/empathy-chatroom-manager.h>
+#include <libempathy/empathy-gsettings.h>
#include <libempathy/empathy-utils.h>
#include <libempathy/empathy-tp-contact-factory.h>
#include <libempathy/empathy-contact-list.h>
#include <libempathy-gtk/empathy-images.h>
-#include <libempathy-gtk/empathy-conf.h>
#include <libempathy-gtk/empathy-contact-dialogs.h>
#include <libempathy-gtk/empathy-log-window.h>
#include <libempathy-gtk/empathy-geometry.h>
#include <libempathy-gtk/empathy-smiley-manager.h>
-#include <libempathy-gtk/empathy-sound.h>
+#include <libempathy-gtk/empathy-sound-manager.h>
#include <libempathy-gtk/empathy-ui-utils.h>
#include <libempathy-gtk/empathy-notify-manager.h>
#define DEBUG_FLAG EMPATHY_DEBUG_CHAT
#include <libempathy/empathy-debug.h>
-typedef struct {
- EmpathyChatWindow *window;
- EmpathyChat *chat;
-} NotificationData;
+/* Macro to compare guint32 X timestamps, while accounting for wrapping around
+ */
+#define X_EARLIER_OR_EQL(t1, t2) \
+ ((t1 <= t2 && ((t2 - t1) < G_MAXUINT32/2)) \
+ || (t1 >= t2 && (t1 - t2) > (G_MAXUINT32/2)) \
+ )
#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyChatWindow)
typedef struct {
GtkWidget *dialog;
GtkWidget *notebook;
NotifyNotification *notification;
- NotificationData *notification_data;
GtkTargetList *contact_targets;
GtkTargetList *file_targets;
GtkUIManager *ui_manager;
GtkAction *menu_conv_insert_smiley;
GtkAction *menu_conv_favorite;
+ GtkAction *menu_conv_always_urgent;
GtkAction *menu_conv_toggle_contacts;
GtkAction *menu_edit_cut;
GtkAction *menu_tabs_left;
GtkAction *menu_tabs_right;
GtkAction *menu_tabs_detach;
+
+ /* Last user action time we acted upon to show a tab */
+ guint32 x_user_action_time;
+
+ GSettings *gsettings_chat;
+ GSettings *gsettings_notif;
+ GSettings *gsettings_ui;
+
+ EmpathySoundManager *sound_mgr;
} EmpathyChatWindowPriv;
static GList *chat_windows = NULL;
static const guint tab_accel_keys[] = {
- GDK_1, GDK_2, GDK_3, GDK_4, GDK_5,
- GDK_6, GDK_7, GDK_8, GDK_9, GDK_0
+ GDK_KEY_1, GDK_KEY_2, GDK_KEY_3, GDK_KEY_4, GDK_KEY_5,
+ GDK_KEY_6, GDK_KEY_7, GDK_KEY_8, GDK_KEY_9, GDK_KEY_0
};
typedef enum {
static void chat_window_update (EmpathyChatWindow *window);
+static void empathy_chat_window_add_chat (EmpathyChatWindow *window,
+ EmpathyChat *chat);
+
+static void empathy_chat_window_remove_chat (EmpathyChatWindow *window,
+ EmpathyChat *chat);
+
+static void empathy_chat_window_move_chat (EmpathyChatWindow *old_window,
+ EmpathyChatWindow *new_window,
+ EmpathyChat *chat);
+
+static void empathy_chat_window_get_nb_chats (EmpathyChatWindow *self,
+ guint *nb_rooms,
+ guint *nb_private);
+
G_DEFINE_TYPE (EmpathyChatWindow, empathy_chat_window, G_TYPE_OBJECT);
static void
"/chats_menubar/menu_contact");
orig_submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu));
- if (orig_submenu == NULL || !GTK_WIDGET_VISIBLE (orig_submenu)) {
+ if (orig_submenu == NULL || !gtk_widget_get_visible (orig_submenu)) {
submenu = empathy_chat_get_contact_menu (priv->current_chat);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), submenu);
gtk_widget_show (menu);
} else {
- empathy_signal_connect_weak (orig_submenu,
+ tp_g_signal_connect_object (orig_submenu,
"notify::visible",
(GCallback)_submenu_notify_visible_changed_cb,
- G_OBJECT (window));
+ window, 0);
}
}
gtk_window_set_icon_name (GTK_WINDOW (priv->dialog),
EMPATHY_IMAGE_MESSAGE);
} else {
- empathy_conf_get_bool (empathy_conf_get (),
- EMPATHY_PREFS_CHAT_AVATAR_IN_ICON,
- &avatar_in_icon);
+ avatar_in_icon = g_settings_get_boolean (priv->gsettings_chat,
+ EMPATHY_PREFS_CHAT_AVATAR_IN_ICON);
if (n_chats == 1 && avatar_in_icon) {
remote_contact = empathy_chat_get_remote_contact (priv->current_chat);
DEBUG ("This room %s favorite", found ? "is" : "is not");
gtk_toggle_action_set_active (
GTK_TOGGLE_ACTION (priv->menu_conv_favorite), found);
+
+ if (chatroom != NULL)
+ found = empathy_chatroom_is_always_urgent (chatroom);
+
+ gtk_toggle_action_set_active (
+ GTK_TOGGLE_ACTION (priv->menu_conv_always_urgent),
+ found);
}
gtk_action_set_visible (priv->menu_conv_favorite, is_room);
+ gtk_action_set_visible (priv->menu_conv_always_urgent, is_room);
/* Show contacts menu */
g_object_get (priv->current_chat,
account = empathy_chat_get_account (priv->current_chat);
room = empathy_chat_get_id (priv->current_chat);
- chatroom = empathy_chatroom_manager_find (priv->chatroom_manager,
- account, room);
+ chatroom = empathy_chatroom_manager_ensure_chatroom (
+ priv->chatroom_manager,
+ account,
+ room,
+ empathy_chat_get_name (priv->current_chat));
- if (chatroom == NULL) {
- const gchar *name;
+ empathy_chatroom_set_favorite (chatroom, active);
+ g_object_unref (chatroom);
+}
- name = empathy_chat_get_name (priv->current_chat);
- chatroom = empathy_chatroom_new_full (account, room, name, FALSE);
- empathy_chatroom_manager_add (priv->chatroom_manager, chatroom);
- g_object_unref (chatroom);
- }
+static void
+chat_window_always_urgent_toggled_cb (GtkToggleAction *toggle_action,
+ EmpathyChatWindow *window)
+{
+ EmpathyChatWindowPriv *priv = GET_PRIV (window);
+ gboolean active;
+ TpAccount *account;
+ const gchar *room;
+ EmpathyChatroom *chatroom;
- empathy_chatroom_set_favorite (chatroom, active);
+ active = gtk_toggle_action_get_active (toggle_action);
+ account = empathy_chat_get_account (priv->current_chat);
+ room = empathy_chat_get_id (priv->current_chat);
+
+ chatroom = empathy_chatroom_manager_ensure_chatroom (
+ priv->chatroom_manager,
+ account,
+ room,
+ empathy_chat_get_name (priv->current_chat));
+
+ empathy_chatroom_set_always_urgent (chatroom, active);
+ g_object_unref (chatroom);
}
static void
}
static void
-got_contact_cb (EmpathyTpContactFactory *factory,
+got_contact_cb (TpConnection *connection,
EmpathyContact *contact,
const GError *error,
gpointer user_data,
if (response == GTK_RESPONSE_ACCEPT) {
TpConnection *connection;
- EmpathyTpContactFactory *factory;
const char *id;
id = empathy_contact_selector_dialog_get_selected (
- EMPATHY_CONTACT_SELECTOR_DIALOG (dialog), NULL);
+ EMPATHY_CONTACT_SELECTOR_DIALOG (dialog), NULL, NULL);
if (EMP_STR_EMPTY (id)) goto out;
connection = tp_channel_borrow_connection (channel);
- factory = empathy_tp_contact_factory_dup_singleton (connection);
-
- empathy_tp_contact_factory_get_from_id (factory, id,
+ empathy_tp_contact_factory_get_from_id (connection, id,
got_contact_cb, tp_chat, NULL, NULL);
-
- g_object_unref (factory);
}
out:
{
EmpathyChatWindowPriv *priv;
EmpathyChat *chat;
- gint index_;
+ gint index_, num_pages;
priv = GET_PRIV (window);
gtk_notebook_reorder_child (GTK_NOTEBOOK (priv->notebook),
GTK_WIDGET (chat),
index_ - 1);
+
+ num_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
+ chat_window_menu_context_update (priv, num_pages);
}
static void
{
EmpathyChatWindowPriv *priv;
EmpathyChat *chat;
- gint index_;
+ gint index_, num_pages;
priv = GET_PRIV (window);
gtk_notebook_reorder_child (GTK_NOTEBOOK (priv->notebook),
GTK_WIDGET (chat),
index_ + 1);
+
+ num_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
+ chat_window_menu_context_update (priv, num_pages);
+}
+
+static EmpathyChatWindow *
+empathy_chat_window_new (void)
+{
+ return EMPATHY_CHAT_WINDOW (g_object_new (EMPATHY_TYPE_CHAT_WINDOW, NULL));
}
static void
gtk_window_set_urgency_hint (GTK_WINDOW (priv->dialog), urgent);
}
-static void
-free_notification_data (NotificationData *data)
-{
- g_object_unref (data->chat);
- g_slice_free (NotificationData, data);
-}
-
static void
chat_window_notification_closed_cb (NotifyNotification *notify,
- NotificationData *cb_data)
+ EmpathyChatWindow *self)
{
- EmpathyChatWindowPriv *priv = GET_PRIV (cb_data->window);
+ EmpathyChatWindowPriv *priv = GET_PRIV (self);
g_object_unref (notify);
- free_notification_data (cb_data);
-
if (priv->notification == notify) {
priv->notification = NULL;
- priv->notification_data = NULL;
}
}
if (!empathy_notify_manager_notification_is_enabled (priv->notify_mgr)) {
return;
} else {
- empathy_conf_get_bool (empathy_conf_get (),
- EMPATHY_PREFS_NOTIFICATIONS_FOCUS, &res);
+ res = g_settings_get_boolean (priv->gsettings_notif,
+ EMPATHY_PREFS_NOTIFICATIONS_FOCUS);
+
if (!res) {
return;
}
}
sender = empathy_message_get_sender (message);
- header = empathy_contact_get_name (sender);
+ header = empathy_contact_get_alias (sender);
body = empathy_message_get_body (message);
escaped = g_markup_escape_text (body, -1);
has_x_canonical_append = empathy_notify_manager_has_capability (
notify_notification_update (notification,
header, escaped, NULL);
} else {
- NotificationData *cb_data = cb_data = g_slice_new0 (NotificationData);
-
- cb_data->chat = g_object_ref (chat);
- cb_data->window = window;
-
/* if the notification server supports x-canonical-append,
the hint will be added, so that the message from the
just created notification will be automatically appended
to an existing notification with the same title.
In this way the previous message will not be lost: the new
message will appear below it, in the same notification */
- notification = notify_notification_new (header, escaped, NULL, NULL);
+ notification = notify_notification_new (header, escaped, NULL);
if (priv->notification == NULL) {
priv->notification = notification;
- priv->notification_data = cb_data;
}
notify_notification_set_timeout (notification, NOTIFY_EXPIRES_DEFAULT);
- g_signal_connect (notification, "closed",
- G_CALLBACK (chat_window_notification_closed_cb), cb_data);
+ tp_g_signal_connect_object (notification, "closed",
+ G_CALLBACK (chat_window_notification_closed_cb), window, 0);
if (has_x_canonical_append) {
notify_notification_set_hint_string (notification,
g_free (markup);
}
+static gboolean
+empathy_chat_window_has_focus (EmpathyChatWindow *window)
+{
+ EmpathyChatWindowPriv *priv;
+ gboolean has_focus;
+
+ g_return_val_if_fail (EMPATHY_IS_CHAT_WINDOW (window), FALSE);
+
+ priv = GET_PRIV (window);
+
+ g_object_get (priv->dialog, "has-toplevel-focus", &has_focus, NULL);
+
+ return has_focus;
+}
+
static void
chat_window_new_message_cb (EmpathyChat *chat,
EmpathyMessage *message,
+ gboolean pending,
EmpathyChatWindow *window)
{
EmpathyChatWindowPriv *priv;
sender = empathy_message_get_sender (message);
if (empathy_contact_is_user (sender)) {
- empathy_sound_play (GTK_WIDGET (priv->dialog),
+ empathy_sound_manager_play (priv->sound_mgr, GTK_WIDGET (priv->dialog),
EMPATHY_SOUND_MESSAGE_OUTGOING);
}
/* If empathy_chat_is_room () returns TRUE, that means it's a named MUC.
* If empathy_chat_get_remote_contact () returns NULL, that means it's
* an unamed MUC (msn-like).
- * In case of a MUC, we set urgency only if the message contains our
- * alias. */
+ * In case of a MUC, we set urgency if either:
+ * a) the chatroom's always_urgent property is TRUE
+ * b) the message contains our alias
+ */
if (empathy_chat_is_room (chat) ||
empathy_chat_get_remote_contact (chat) == NULL) {
- needs_urgency = empathy_message_should_highlight (message);
+ TpAccount *account;
+ const gchar *room;
+ EmpathyChatroom *chatroom;
+
+ account = empathy_chat_get_account (chat);
+ room = empathy_chat_get_id (chat);
+
+ chatroom = empathy_chatroom_manager_find (priv->chatroom_manager,
+ account, room);
+
+ if (empathy_chatroom_is_always_urgent (chatroom)) {
+ needs_urgency = TRUE;
+ } else {
+ needs_urgency = empathy_message_should_highlight (message);
+ }
} else {
needs_urgency = TRUE;
}
chat_window_set_highlight_room_tab_label (chat);
}
- empathy_sound_play (GTK_WIDGET (priv->dialog),
+ empathy_sound_manager_play (priv->sound_mgr, GTK_WIDGET (priv->dialog),
EMPATHY_SOUND_MESSAGE_INCOMING);
- chat_window_show_or_update_notification (window, message, chat);
+
+ /* Pending messages have already been displayed in the approver, so we don't
+ * display a notification for those. */
+ if (!pending)
+ chat_window_show_or_update_notification (window, message, chat);
}
- /* update the number of unread messages */
+ /* update the number of unread messages and the window icon */
chat_window_title_update (priv);
+ chat_window_icon_update (priv);
}
static GtkNotebook *
-chat_window_detach_hook (GtkNotebook *source,
+notebook_create_window_cb (GtkNotebook *source,
GtkWidget *page,
gint x,
gint y,
empathy_chat_window_move_chat (window, new_window, chat);
- gtk_window_move (GTK_WINDOW (priv->dialog), x, y);
gtk_widget_show (priv->dialog);
+ gtk_window_move (GTK_WINDOW (priv->dialog), x, y);
return NULL;
}
static void
chat_window_page_switched_cb (GtkNotebook *notebook,
- GtkNotebookPage *page,
+ gpointer ignore, /* see note below */
gint page_num,
EmpathyChatWindow *window)
{
priv = GET_PRIV (window);
+ /* N.B. in GTK+ 3 child is passed as the first argument to the signal,
+ * but we can't use that while trying to retain GTK+ 2.x compatibility.
+ */
child = gtk_notebook_get_nth_page (notebook, page_num);
chat = EMPATHY_CHAT (child);
}
if (!chat) {
- TpConnection *connection;
-
- connection = tp_account_get_connection (account);
-
- if (connection) {
- empathy_dispatcher_chat_with_contact_id (
- connection, contact_id, NULL, NULL);
- }
+ empathy_dispatcher_chat_with_contact_id (
+ account, contact_id, gtk_get_current_event_time ());
g_strfreev (strv);
return;
}
/* Added to take care of any outstanding chat events */
- empathy_chat_window_present_chat (chat);
+ empathy_chat_window_present_chat (chat,
+ TP_USER_ACTION_TIME_NOT_USER_ACTION);
/* We should return TRUE to remove the data when doing
* GDK_ACTION_MOVE, but we don't here otherwise it has
g_object_unref (priv->ui_manager);
g_object_unref (priv->chatroom_manager);
g_object_unref (priv->notify_mgr);
+ g_object_unref (priv->gsettings_chat);
+ g_object_unref (priv->gsettings_notif);
+ g_object_unref (priv->gsettings_ui);
+ g_object_unref (priv->sound_mgr);
if (priv->notification != NULL) {
notify_notification_close (priv->notification, NULL);
priv->notification = NULL;
- free_notification_data (priv->notification_data);
- priv->notification_data = NULL;
}
if (priv->contact_targets) {
" ythickness = 0\n"
"}\n"
"widget \"*.empathy-close-button\" style \"empathy-close-button-style\"");
-
- gtk_notebook_set_window_creation_hook (chat_window_detach_hook, NULL, NULL);
}
static void
"ui_manager", &priv->ui_manager,
"menu_conv_insert_smiley", &priv->menu_conv_insert_smiley,
"menu_conv_favorite", &priv->menu_conv_favorite,
+ "menu_conv_always_urgent", &priv->menu_conv_always_urgent,
"menu_conv_toggle_contacts", &priv->menu_conv_toggle_contacts,
"menu_edit_cut", &priv->menu_edit_cut,
"menu_edit_copy", &priv->menu_edit_copy,
"menu_conv", "activate", chat_window_conv_activate_cb,
"menu_conv_clear", "activate", chat_window_clear_activate_cb,
"menu_conv_favorite", "toggled", chat_window_favorite_toggled_cb,
+ "menu_conv_always_urgent", "toggled", chat_window_always_urgent_toggled_cb,
"menu_conv_toggle_contacts", "toggled", chat_window_contacts_toggled_cb,
"menu_conv_invite_participant", "activate", chat_window_invite_participant_activate_cb,
"menu_conv_close", "activate", chat_window_close_activate_cb,
g_object_ref (priv->ui_manager);
g_object_unref (gui);
+ priv->gsettings_chat = g_settings_new (EMPATHY_PREFS_CHAT_SCHEMA);
+ priv->gsettings_notif = g_settings_new (EMPATHY_PREFS_NOTIFICATIONS_SCHEMA);
+ priv->gsettings_ui = g_settings_new (EMPATHY_PREFS_UI_SCHEMA);
priv->chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL);
+ priv->sound_mgr = empathy_sound_manager_dup_singleton ();
+
priv->notebook = gtk_notebook_new ();
- gtk_notebook_set_group (GTK_NOTEBOOK (priv->notebook), "EmpathyChatWindow");
+
+ g_signal_connect (priv->notebook, "create-window",
+ G_CALLBACK (notebook_create_window_cb), window);
+
+ gtk_notebook_set_group_name (GTK_NOTEBOOK (priv->notebook),
+ "EmpathyChatWindow");
gtk_notebook_set_scrollable (GTK_NOTEBOOK (priv->notebook), TRUE);
gtk_notebook_popup_enable (GTK_NOTEBOOK (priv->notebook));
gtk_box_pack_start (GTK_BOX (chat_vbox), priv->notebook, TRUE, TRUE, 0);
priv->chat_manager = empathy_chat_manager_dup_singleton ();
priv->chat_manager_chats_changed_id =
- g_signal_connect (priv->chat_manager, "chats-changed",
+ g_signal_connect (priv->chat_manager, "closed-chats-changed",
G_CALLBACK (chat_window_chat_manager_chats_changed_cb),
window);
chat_window_chat_manager_chats_changed_cb (priv->chat_manager,
- empathy_chat_manager_get_num_chats (priv->chat_manager),
+ empathy_chat_manager_get_num_closed_chats (priv->chat_manager),
window);
}
-EmpathyChatWindow *
-empathy_chat_window_new (void)
+static GtkWidget *
+empathy_chat_window_get_dialog (EmpathyChatWindow *window)
{
- return EMPATHY_CHAT_WINDOW (g_object_new (EMPATHY_TYPE_CHAT_WINDOW, NULL));
+ EmpathyChatWindowPriv *priv;
+
+ g_return_val_if_fail (window != NULL, NULL);
+
+ priv = GET_PRIV (window);
+
+ return priv->dialog;
}
-/* Returns the window to open a new tab in if there is only one window
- * visble, otherwise, returns NULL indicating that a new window should
- * be added.
+/* Returns the window to open a new tab in if there is a suitable window,
+ * otherwise, returns NULL indicating that a new window should be added.
*/
-EmpathyChatWindow *
+static EmpathyChatWindow *
empathy_chat_window_get_default (gboolean room)
{
+ GSettings *gsettings = g_settings_new (EMPATHY_PREFS_UI_SCHEMA);
GList *l;
gboolean separate_windows = TRUE;
- empathy_conf_get_bool (empathy_conf_get (),
- EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS,
- &separate_windows);
+ separate_windows = g_settings_get_boolean (gsettings,
+ EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS);
+
+ g_object_unref (gsettings);
if (separate_windows) {
/* Always create a new window */
EmpathyChatWindowPriv *priv;
EmpathyChatWindow *chat_window;
GtkWidget *dialog;
+ guint nb_rooms, nb_private;
chat_window = l->data;
priv = GET_PRIV (chat_window);
dialog = empathy_chat_window_get_dialog (chat_window);
- if (empathy_window_get_is_visible (GTK_WINDOW (dialog))) {
- guint nb_rooms, nb_private;
- empathy_chat_window_get_nb_chats (chat_window, &nb_rooms, &nb_private);
- /* Skip the window if there aren't any rooms in it */
- if (room && nb_rooms == 0)
- continue;
+ empathy_chat_window_get_nb_chats (chat_window, &nb_rooms, &nb_private);
- /* Skip the window if there aren't any 1-1 chats in it */
- if (!room && nb_private == 0)
- continue;
+ /* Skip the window if there aren't any rooms in it */
+ if (room && nb_rooms == 0)
+ continue;
- /* Found a visible window on this desktop */
- return chat_window;
- }
+ /* Skip the window if there aren't any 1-1 chats in it */
+ if (!room && nb_private == 0)
+ continue;
+
+ /* Found a window on this desktop, make it visible if necessary */
+ if (!empathy_window_get_is_visible (GTK_WINDOW (dialog)))
+ empathy_window_present (GTK_WINDOW (dialog));
+ return chat_window;
}
return NULL;
}
-GtkWidget *
-empathy_chat_window_get_dialog (EmpathyChatWindow *window)
-{
- EmpathyChatWindowPriv *priv;
-
- g_return_val_if_fail (window != NULL, NULL);
-
- priv = GET_PRIV (window);
-
- return priv->dialog;
-}
-
-void
+static void
empathy_chat_window_add_chat (EmpathyChatWindow *window,
EmpathyChat *chat)
{
const gchar *name = "chat-window";
gboolean separate_windows;
- empathy_conf_get_bool (empathy_conf_get (),
- EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS,
- &separate_windows);
+ separate_windows = g_settings_get_boolean (priv->gsettings_ui,
+ EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS);
+
+ if (empathy_chat_is_room (chat))
+ name = "room-window";
if (separate_windows) {
+ gint x, y;
+
+ /* Save current position of the window */
+ gtk_window_get_position (GTK_WINDOW (priv->dialog), &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 (priv->dialog), 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 (priv->dialog), 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);
}
- else if (empathy_chat_is_room (chat)) {
- name = "room-window";
- }
empathy_geometry_bind (GTK_WINDOW (priv->dialog), name);
}
DEBUG ("Chat added (%d references)", G_OBJECT (chat)->ref_count);
}
-void
+static void
empathy_chat_window_remove_chat (EmpathyChatWindow *window,
EmpathyChat *chat)
{
g_object_unref (chat);
}
-void
+static void
empathy_chat_window_move_chat (EmpathyChatWindow *old_window,
EmpathyChatWindow *new_window,
EmpathyChat *chat)
g_object_unref (chat);
}
-void
+static void
empathy_chat_window_switch_to_chat (EmpathyChatWindow *window,
EmpathyChat *chat)
{
page_num);
}
-gboolean
-empathy_chat_window_has_focus (EmpathyChatWindow *window)
-{
- EmpathyChatWindowPriv *priv;
- gboolean has_focus;
-
- g_return_val_if_fail (EMPATHY_IS_CHAT_WINDOW (window), FALSE);
-
- priv = GET_PRIV (window);
-
- g_object_get (priv->dialog, "has-toplevel-focus", &has_focus, NULL);
-
- return has_focus;
-}
-
EmpathyChat *
empathy_chat_window_find_chat (TpAccount *account,
const gchar *id)
}
void
-empathy_chat_window_present_chat (EmpathyChat *chat)
+empathy_chat_window_present_chat (EmpathyChat *chat,
+ gint64 timestamp)
{
EmpathyChatWindow *window;
EmpathyChatWindowPriv *priv;
+ guint32 x_timestamp;
g_return_if_fail (EMPATHY_IS_CHAT (chat));
window = empathy_chat_window_get_default (empathy_chat_is_room (chat));
if (!window) {
window = empathy_chat_window_new ();
+ gtk_widget_show_all (GET_PRIV (window)->dialog);
}
empathy_chat_window_add_chat (window, chat);
}
+ /* Don't force the window to show itself when it wasn't
+ * an action by the user
+ */
+ if (!tp_user_action_time_should_present (timestamp, &x_timestamp))
+ return;
+
priv = GET_PRIV (window);
+
+ if (x_timestamp != GDK_CURRENT_TIME) {
+ /* Don't present or switch tab if the action was earlier than the
+ * last actions X time, accounting for overflow and the first ever
+ * presentation */
+
+ if (priv->x_user_action_time != 0
+ && X_EARLIER_OR_EQL (x_timestamp, priv->x_user_action_time))
+ return;
+
+ priv->x_user_action_time = x_timestamp;
+ }
+
empathy_chat_window_switch_to_chat (window, chat);
- empathy_window_present (GTK_WINDOW (priv->dialog));
+ empathy_window_present_with_time (GTK_WINDOW (priv->dialog),
+ x_timestamp);
- gtk_widget_grab_focus (chat->input_text_view);
+ gtk_widget_grab_focus (chat->input_text_view);
}
-void
+static void
empathy_chat_window_get_nb_chats (EmpathyChatWindow *self,
guint *nb_rooms,
guint *nb_private)