Mercurial > pidgin
annotate src/gtkmenutray.c @ 12116:e75ef7aa913e
[gaim-migrate @ 14416]
" This patch implements a replacement for the queuing
system from 1.x. It also obsoletes a previous patch
[#1338873] I submitted to prioritize the unseen states
in gtk conversations.
The attached envelope.png is ripped from the
msgunread.png already included in gaim. It should be
dropped in the pixmaps directory (Makefile.am is
updated accordingly in this patch).
The two separate queuing preferences from 1.x, queuing
messages while away and queuing all new messages (from
docklet), are replaced with a single 3-way preference
for conversations. The new preference is "Hide new IM
conversations". This preference can be set to never,
away and always.
When a gtk conversation is created, it may be placed in
a hidden conversation window instead of being placed
normally. This decision is based upon the preference
and possibly the away state of the account the
conversation is being created for. This *will* effect
conversations the user explicitly requests to be
created, so in these cases the caller must be sure to
present the conversation to the user, using
gaim_gtkconv_present_conversation(). This is done
already in gtkdialogs.c which handles creating
conversations requested by the user from gaim proper
(menus, double-clicking on budy in blist, etc.).
The main advantage to not queuing messages is that the
conversations exist, the message is written to the
conversation (and logged if appropriate) and the unseen
state is set on the conversation. This means no
additional features are needed to track whether there
are queued messages or not, just use the unseen state
on conversations.
Since conversations may not be visible (messages
"queued"), gaim proper needs some notification that
there are messages waiting. I opted for a menutray icon
that shows up when an im conversation has an unseen
message. Clicking this icon will focus (and show if
hidden) the first conversation with an unseen message.
This is essentially the same behavior of the docklet in
cvs right now, except that the icon is only visible
when there is a conversation with an unread message.
The api that is added is flexible enough to allow
either the docklet or the new blist menutray icon to be
visible for conversations of any/all types and for
unseen messages >= any state. Currently they are set to
only IM conversations and only unseen states >= TEXT
(system messages and no log messages will not trigger
blinking the docklet or showing the blist tray icon),
but these could be made preferences relatively easily
in the future. Other plugins could probably benefit as
well: gaim_gtk_conversations_get_first_unseen().
There is probably some limit to comment size, so I'll
stop rambling now. If anyone has more
questions/comments, catch me in #gaim, here or on
gaim-devel."
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Wed, 16 Nov 2005 18:17:01 +0000 |
parents | 91aaa1b3ac30 |
children |
rev | line source |
---|---|
11553 | 1 /* |
2 * Gaim is the legal property of its developers, whose names are too numerous | |
3 * to list here. Please refer to the COPYRIGHT file distributed with this | |
4 * source distribution. | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 */ | |
11908
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
20 #include "debug.h" |
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
21 |
11553 | 22 #include "gtkmenutray.h" |
23 | |
12008 | 24 #include <gtk/gtkeventbox.h> |
11787
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
25 #include <gtk/gtkiconfactory.h> |
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
26 #include <gtk/gtkversion.h> |
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
27 |
11553 | 28 /****************************************************************************** |
29 * Enums | |
30 *****************************************************************************/ | |
31 enum { | |
32 PROP_ZERO = 0, | |
33 PROP_BOX | |
34 }; | |
35 | |
36 /****************************************************************************** | |
37 * Globals | |
38 *****************************************************************************/ | |
39 static GObjectClass *parent_class = NULL; | |
40 | |
41 /****************************************************************************** | |
42 * Internal Stuff | |
43 *****************************************************************************/ | |
44 | |
45 /****************************************************************************** | |
46 * Item Stuff | |
47 *****************************************************************************/ | |
48 static void | |
49 gaim_gtk_menu_tray_select(GtkItem *item) { | |
50 /* this may look like nothing, but it's really overriding the | |
51 * GtkMenuItem's select function so that it doesn't get highlighted like | |
52 * a normal menu item would. | |
53 */ | |
54 } | |
55 | |
56 static void | |
57 gaim_gtk_menu_tray_deselect(GtkItem *item) { | |
58 /* Probably not necessary, but I'd rather be safe than sorry. We're | |
59 * overridding the select, so it makes sense to override deselect as well. | |
60 */ | |
61 } | |
62 | |
63 /****************************************************************************** | |
64 * Widget Stuff | |
65 *****************************************************************************/ | |
66 | |
67 /****************************************************************************** | |
68 * Object Stuff | |
69 *****************************************************************************/ | |
70 static void | |
71 gaim_gtk_menu_tray_get_property(GObject *obj, guint param_id, GValue *value, | |
72 GParamSpec *pspec) | |
73 { | |
74 GaimGtkMenuTray *menu_tray = GAIM_GTK_MENU_TRAY(obj); | |
75 | |
76 switch(param_id) { | |
77 case PROP_BOX: | |
78 g_value_set_object(value, gaim_gtk_menu_tray_get_box(menu_tray)); | |
79 break; | |
80 default: | |
81 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); | |
82 break; | |
83 } | |
84 } | |
85 | |
86 static void | |
87 gaim_gtk_menu_tray_finalize(GObject *obj) { | |
11599
767e3c0c5062
[gaim-migrate @ 13869]
Gary Kramlich <grim@reaperworld.com>
parents:
11558
diff
changeset
|
88 #if 0 |
767e3c0c5062
[gaim-migrate @ 13869]
Gary Kramlich <grim@reaperworld.com>
parents:
11558
diff
changeset
|
89 /* This _might_ be leaking, but I have a sneaking suspicion that the widget is |
767e3c0c5062
[gaim-migrate @ 13869]
Gary Kramlich <grim@reaperworld.com>
parents:
11558
diff
changeset
|
90 * getting destroyed in GtkContainer's finalize function. But if were are |
767e3c0c5062
[gaim-migrate @ 13869]
Gary Kramlich <grim@reaperworld.com>
parents:
11558
diff
changeset
|
91 * leaking here, be sure to figure out why this causes a crash. |
767e3c0c5062
[gaim-migrate @ 13869]
Gary Kramlich <grim@reaperworld.com>
parents:
11558
diff
changeset
|
92 * -- Gary |
767e3c0c5062
[gaim-migrate @ 13869]
Gary Kramlich <grim@reaperworld.com>
parents:
11558
diff
changeset
|
93 */ |
11558 | 94 GaimGtkMenuTray *tray = GAIM_GTK_MENU_TRAY(obj); |
11599
767e3c0c5062
[gaim-migrate @ 13869]
Gary Kramlich <grim@reaperworld.com>
parents:
11558
diff
changeset
|
95 |
11558 | 96 if(GTK_IS_WIDGET(tray->tray)) |
97 gtk_widget_destroy(GTK_WIDGET(tray->tray)); | |
11599
767e3c0c5062
[gaim-migrate @ 13869]
Gary Kramlich <grim@reaperworld.com>
parents:
11558
diff
changeset
|
98 #endif |
11553 | 99 |
100 G_OBJECT_CLASS(parent_class)->finalize(obj); | |
101 } | |
102 | |
103 static void | |
104 gaim_gtk_menu_tray_class_init(GaimGtkMenuTrayClass *klass) { | |
105 GObjectClass *object_class = G_OBJECT_CLASS(klass); | |
106 GtkItemClass *item_class = GTK_ITEM_CLASS(klass); | |
107 GParamSpec *pspec; | |
108 | |
109 parent_class = g_type_class_peek_parent(klass); | |
110 | |
111 object_class->finalize = gaim_gtk_menu_tray_finalize; | |
112 object_class->get_property = gaim_gtk_menu_tray_get_property; | |
113 | |
114 item_class->select = gaim_gtk_menu_tray_select; | |
115 item_class->deselect = gaim_gtk_menu_tray_deselect; | |
116 | |
117 pspec = g_param_spec_object("box", "The box", | |
118 "The box", | |
119 GTK_TYPE_BOX, | |
120 G_PARAM_READABLE); | |
121 g_object_class_install_property(object_class, PROP_BOX, pspec); | |
122 } | |
123 | |
124 static void | |
125 gaim_gtk_menu_tray_init(GaimGtkMenuTray *menu_tray) { | |
11787
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
126 GtkWidget *widget = GTK_WIDGET(menu_tray); |
11888 | 127 #if GTK_CHECK_VERSION(2,2,0) |
11787
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
128 GtkSettings *settings; |
11888 | 129 #endif |
11787
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
130 gint height = -1; |
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
131 |
11553 | 132 gtk_menu_item_set_right_justified(GTK_MENU_ITEM(menu_tray), TRUE); |
12008 | 133 |
11558 | 134 if(!GTK_IS_WIDGET(menu_tray->tray)) |
135 menu_tray->tray = gtk_hbox_new(FALSE, 0); | |
11553 | 136 |
11908
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
137 menu_tray->tooltips = gtk_tooltips_new(); |
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
138 |
11787
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
139 #if GTK_CHECK_VERSION(2,2,0) |
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
140 settings = |
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
141 gtk_settings_get_for_screen(gtk_widget_get_screen(widget)); |
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
142 |
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
143 if(gtk_icon_size_lookup_for_settings(settings, GTK_ICON_SIZE_MENU, |
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
144 NULL, &height)) |
11888 | 145 #else |
146 if(gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, NULL, &height)) | |
147 #endif | |
11787
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
148 { |
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
149 gtk_widget_set_size_request(widget, -1, height); |
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
150 } |
c9188d3eb9d3
[gaim-migrate @ 14078]
Gary Kramlich <grim@reaperworld.com>
parents:
11599
diff
changeset
|
151 |
11558 | 152 gtk_container_add(GTK_CONTAINER(menu_tray), menu_tray->tray); |
11553 | 153 |
11558 | 154 gtk_widget_show(menu_tray->tray); |
11553 | 155 } |
156 | |
157 /****************************************************************************** | |
158 * API | |
159 *****************************************************************************/ | |
160 GType | |
161 gaim_gtk_menu_tray_get_gtype(void) { | |
162 static GType type = 0; | |
163 | |
164 if(type == 0) { | |
165 static const GTypeInfo info = { | |
166 sizeof(GaimGtkMenuTrayClass), | |
167 NULL, | |
168 NULL, | |
169 (GClassInitFunc)gaim_gtk_menu_tray_class_init, | |
170 NULL, | |
171 NULL, | |
172 sizeof(GaimGtkMenuTray), | |
173 0, | |
174 (GInstanceInitFunc)gaim_gtk_menu_tray_init, | |
175 NULL | |
176 }; | |
177 | |
178 type = g_type_register_static(GTK_TYPE_MENU_ITEM, | |
179 "GaimGtkMenuTray", | |
180 &info, 0); | |
181 } | |
182 | |
183 return type; | |
184 } | |
185 | |
186 GtkWidget * | |
187 gaim_gtk_menu_tray_new() { | |
188 return g_object_new(GAIM_GTK_TYPE_MENU_TRAY, NULL); | |
189 } | |
190 | |
191 GtkWidget * | |
192 gaim_gtk_menu_tray_get_box(GaimGtkMenuTray *menu_tray) { | |
193 g_return_val_if_fail(GAIM_GTK_IS_MENU_TRAY(menu_tray), NULL); | |
11558 | 194 return menu_tray->tray; |
11553 | 195 } |
196 | |
12008 | 197 static void |
198 gaim_gtk_menu_tray_add(GaimGtkMenuTray *menu_tray, GtkWidget *widget, | |
199 const char *tooltip, gboolean prepend) | |
11908
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
200 { |
11553 | 201 g_return_if_fail(GAIM_GTK_IS_MENU_TRAY(menu_tray)); |
202 g_return_if_fail(GTK_IS_WIDGET(widget)); | |
203 | |
12008 | 204 if (GTK_WIDGET_NO_WINDOW(widget)) |
205 { | |
206 GtkWidget *event; | |
207 | |
208 event = gtk_event_box_new(); | |
209 gtk_container_add(GTK_CONTAINER(event), widget); | |
210 gtk_widget_show(event); | |
211 widget = event; | |
212 } | |
213 | |
11908
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
214 gaim_gtk_menu_tray_set_tooltip(menu_tray, widget, tooltip); |
12008 | 215 |
216 if (prepend) | |
217 gtk_box_pack_start(GTK_BOX(menu_tray->tray), widget, FALSE, FALSE, 0); | |
218 else | |
219 gtk_box_pack_end(GTK_BOX(menu_tray->tray), widget, FALSE, FALSE, 0); | |
220 } | |
221 | |
222 void | |
223 gaim_gtk_menu_tray_append(GaimGtkMenuTray *menu_tray, GtkWidget *widget, const char *tooltip) | |
224 { | |
225 gaim_gtk_menu_tray_add(menu_tray, widget, tooltip, FALSE); | |
11553 | 226 } |
227 | |
228 void | |
11908
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
229 gaim_gtk_menu_tray_prepend(GaimGtkMenuTray *menu_tray, GtkWidget *widget, const char *tooltip) |
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
230 { |
12008 | 231 gaim_gtk_menu_tray_add(menu_tray, widget, tooltip, TRUE); |
11553 | 232 } |
11908
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
233 |
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
234 void |
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
235 gaim_gtk_menu_tray_set_tooltip(GaimGtkMenuTray *menu_tray, GtkWidget *widget, const char *tooltip) |
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
236 { |
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
237 if (!menu_tray->tooltips) |
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
238 return; |
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
239 |
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
240 /* Should we check whether widget is a child of menu_tray? */ |
12008 | 241 |
242 /* | |
243 * If the widget does not have it's own window, then it | |
244 * must have automatically been added to an event box | |
245 * when it was added to the menu tray. If this is the | |
246 * case, we want to set the tooltip on the widget's parent, | |
247 * not on the widget itself. | |
248 */ | |
11908
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
249 if (GTK_WIDGET_NO_WINDOW(widget)) |
12008 | 250 widget = widget->parent; |
251 | |
252 gtk_tooltips_set_tip(menu_tray->tooltips, widget, tooltip, NULL); | |
11908
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
253 } |
34ea75bdd0c9
[gaim-migrate @ 14199]
Richard Laager <rlaager@wiktel.com>
parents:
11888
diff
changeset
|
254 |