# HG changeset patch # User Daniel Atallah # Date 1123708424 0 # Node ID 409d6a11da511ae9b8481db75082a189435a439a # Parent d424c3bbac8daf01e1805371b6b75bd68589abb5 [gaim-migrate @ 13360] Restrict the conversation scrollback. Current default is 4000 lines. This also fixes the IM images not actually being cleared by gtk_imhtml_clear(). committer: Tailor Script diff -r d424c3bbac8d -r 409d6a11da51 ChangeLog --- a/ChangeLog Wed Aug 10 05:45:17 2005 +0000 +++ b/ChangeLog Wed Aug 10 21:13:44 2005 +0000 @@ -46,6 +46,8 @@ directly * Yahoo! buddy requests to add you to their buddy list now prompt for authorization. + * Conversation buffer scrollback limited to avoid large memory + usage in active conversations. Bug fixes: * People using input methods can now use Enter again. diff -r d424c3bbac8d -r 409d6a11da51 plugins/ChangeLog.API --- a/plugins/ChangeLog.API Wed Aug 10 05:45:17 2005 +0000 +++ b/plugins/ChangeLog.API Wed Aug 10 21:13:44 2005 +0000 @@ -82,6 +82,7 @@ * Changed: "chat-invited" handlers can now return a value to control what happens to the invite (accept, reject, prompt the user). See the Doxygen documentation for the details. + * Added: gtk_imhtml_delete to clear out part of a imhtml buffer version 1.0.0 (09/17/2004): * Added: get_chat_name to the GaimPluginProtocolInfo struct diff -r d424c3bbac8d -r 409d6a11da51 src/gtkconv.c --- a/src/gtkconv.c Wed Aug 10 05:45:17 2005 +0000 +++ b/src/gtkconv.c Wed Aug 10 21:13:44 2005 +0000 @@ -4964,6 +4964,9 @@ GaimConvWindow *win; GaimConnection *gc; int gtk_font_options = 0; + int max_scrollback_lines = gaim_prefs_get_int( + "/gaim/gtk/conversations/scrollback_lines"); + int line_count; char buf2[BUF_LONG]; char mdate[64]; char color[10]; @@ -4978,6 +4981,24 @@ win = gaim_conversation_get_window(conv); + line_count = gtk_text_buffer_get_line_count( + gtk_text_view_get_buffer(GTK_TEXT_VIEW( + gtkconv->imhtml))); +printf("writing to conv - max_scrollback_lines = %d our lines = %d\n", max_scrollback_lines, line_count); + /* If we're sitting at more than 100 lines more than the + max scrollback, trim down to max scrollback */ + if (max_scrollback_lines > 0 + && line_count > (max_scrollback_lines + 100)) { + GtkTextBuffer *text_buffer = gtk_text_view_get_buffer( + GTK_TEXT_VIEW(gtkconv->imhtml)); + GtkTextIter start, end; + + gtk_text_buffer_get_start_iter(text_buffer, &start); + gtk_text_buffer_get_iter_at_line(text_buffer, &end, + (line_count - max_scrollback_lines)); + gtk_imhtml_delete(GTK_IMHTML(gtkconv->imhtml), &start, &end); + } + if (gtk_text_buffer_get_char_count(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)))) gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "
", 0); @@ -6222,6 +6243,7 @@ gaim_prefs_add_bool("/gaim/gtk/conversations/tabs", TRUE); gaim_prefs_add_int("/gaim/gtk/conversations/tab_side", GTK_POS_TOP); gaim_prefs_add_bool("/gaim/gtk/conversations/warn_on_unread_close", TRUE); + gaim_prefs_add_int("/gaim/gtk/conversations/scrollback_lines", 4000); /* Conversations -> Chat */ gaim_prefs_add_none("/gaim/gtk/conversations/chat"); diff -r d424c3bbac8d -r 409d6a11da51 src/gtkimhtml.c --- a/src/gtkimhtml.c Wed Aug 10 05:45:17 2005 +0000 +++ b/src/gtkimhtml.c Wed Aug 10 21:13:44 2005 +0000 @@ -77,6 +77,17 @@ static GtkTextViewClass *parent_class = NULL; +struct scalable_data { + GtkIMHtmlScalable *scalable; + GtkTextMark *mark; +}; + + +struct im_image_data { + int id; + GtkTextMark *mark; +}; + static gboolean gtk_text_view_drag_motion (GtkWidget *widget, GdkDragContext *context, @@ -371,7 +382,8 @@ gtk_text_view_get_right_margin(GTK_TEXT_VIEW(widget)); while(iter){ - GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(iter->data); + struct scalable_data *sd = iter->data; + GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(sd->scalable); scale->scale(scale, rect.width - xminus, rect.height); iter = iter->next; @@ -1139,15 +1151,17 @@ gtk_timeout_remove(imhtml->tip_timer); for(scalables = imhtml->scalables; scalables; scalables = scalables->next) { - GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(scalables->data); + struct scalable_data *sd = scalables->data; + GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(sd->scalable); scale->free(scale); + g_free(sd); } for (l = imhtml->im_images; l; l = l->next) { - int id; - id = GPOINTER_TO_INT(l->data); + struct im_image_data *img_data = l->data; if (imhtml->funcs->image_unref) - imhtml->funcs->image_unref(id); + imhtml->funcs->image_unref(img_data->id); + g_free(img_data); } if (imhtml->clipboard_text_string) { @@ -2463,17 +2477,19 @@ case 42: /* HR (opt) */ { int minus; + struct scalable_data *sd = g_new(struct scalable_data, 1); ws[wpos++] = '\n'; gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); - scalable = gtk_imhtml_hr_new(); + sd->scalable = scalable = gtk_imhtml_hr_new(); gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); scalable->add_to(scalable, imhtml, iter); minus = gtk_text_view_get_left_margin(GTK_TEXT_VIEW(imhtml)) + gtk_text_view_get_right_margin(GTK_TEXT_VIEW(imhtml)); scalable->scale(scalable, rect.width - minus, rect.height); - imhtml->scalables = g_list_append(imhtml->scalables, scalable); + sd->mark = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, iter, TRUE); + imhtml->scalables = g_list_append(imhtml->scalables, sd); ws[0] = '\0'; wpos = 0; ws[wpos++] = '\n'; @@ -2969,23 +2985,53 @@ } void -gtk_imhtml_clear (GtkIMHtml *imhtml) -{ - GList *del; - GtkTextIter start, end; +gtk_imhtml_delete(GtkIMHtml *imhtml, GtkTextIter *start, GtkTextIter *end) { + GList *l; + GSList *sl; + GtkTextIter i; GObject *object = g_object_ref(G_OBJECT(imhtml)); - - gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start); - gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end); - gtk_text_buffer_delete(imhtml->text_buffer, &start, &end); - - for(del = imhtml->scalables; del; del = del->next) { - GtkIMHtmlScalable *scale = del->data; - scale->free(scale); + + if (start == NULL) { + GtkTextIter i_s; + gtk_text_buffer_get_start_iter(imhtml->text_buffer, &i_s); + start = &i_s; + } + + if (end == NULL) { + GtkTextIter i_e; + gtk_text_buffer_get_end_iter(imhtml->text_buffer, &i_e); + end = &i_e; } - - g_list_free(imhtml->scalables); - imhtml->scalables = NULL; + + l = imhtml->scalables; + while (l) { + GList *next = l->next; + struct scalable_data *sd = l->data; + gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, + &i, sd->mark); + if (gtk_text_iter_in_range(&i, start, end)) { + GtkIMHtmlScalable *scale = sd->scalable; + scale->free(scale); + imhtml->scalables = g_list_remove_link(imhtml->scalables, l); + } + l = next; + } + + sl = imhtml->im_images; + while (sl) { + GSList *next = sl->next; + struct im_image_data *img_data = sl->data; + gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, + &i, img_data->mark); + if (gtk_text_iter_in_range(&i, start, end)) { + if (imhtml->funcs->image_unref) + imhtml->funcs->image_unref(img_data->id); + imhtml->im_images = g_slist_delete_link(imhtml->im_images, sl); + g_free(img_data); + } + sl = next; + } + gtk_text_buffer_delete(imhtml->text_buffer, start, end); g_object_unref(object); } @@ -4194,6 +4240,7 @@ gpointer image; GdkRectangle rect; GtkIMHtmlScalable *scalable = NULL; + struct scalable_data *sd; int minus; if (!imhtml->funcs || !imhtml->funcs->image_get || @@ -4226,19 +4273,24 @@ if (pixbuf) { filename = imhtml->funcs->image_get_filename(image); imhtml->funcs->image_ref(id); - imhtml->im_images = g_slist_prepend(imhtml->im_images, GINT_TO_POINTER(id)); + struct im_image_data *t = g_new(struct im_image_data, 1); + t->id = id; + t->mark = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, iter, TRUE); + imhtml->im_images = g_slist_prepend(imhtml->im_images, t); } else { pixbuf = gtk_widget_render_icon(GTK_WIDGET(imhtml), GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_BUTTON, "gtkimhtml-missing-image"); } - scalable = gtk_imhtml_image_new(pixbuf, filename, id); + sd = g_new(struct scalable_data, 1); + sd->scalable = scalable = gtk_imhtml_image_new(pixbuf, filename, id); gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); scalable->add_to(scalable, imhtml, iter); minus = gtk_text_view_get_left_margin(GTK_TEXT_VIEW(imhtml)) + gtk_text_view_get_right_margin(GTK_TEXT_VIEW(imhtml)); scalable->scale(scalable, rect.width - minus, rect.height); - imhtml->scalables = g_list_append(imhtml->scalables, scalable); + sd->mark = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, iter, TRUE); + imhtml->scalables = g_list_append(imhtml->scalables, sd); g_object_unref(G_OBJECT(pixbuf)); } diff -r d424c3bbac8d -r 409d6a11da51 src/gtkimhtml.h --- a/src/gtkimhtml.h Wed Aug 10 05:45:17 2005 +0000 +++ b/src/gtkimhtml.h Wed Aug 10 21:13:44 2005 +0000 @@ -347,11 +347,21 @@ void gtk_imhtml_scroll_to_end(GtkIMHtml *imhtml); /** + * Delete the contents of a GTK+ IM/HTML between start and end. + * + * @param imhtml The GTK+ IM/HTML. + * @param start a postition in the imhtml's buffer + * @param end another postition in the imhtml's buffer + */ +void gtk_imhtml_delete(GtkIMHtml *imhtml, GtkTextIter *start, GtkTextIter *end); + +/** * Purges the contents from a GTK+ IM/HTML and resets formatting. * * @param imhtml The GTK+ IM/HTML. */ -void gtk_imhtml_clear(GtkIMHtml *imhtml); +#define gtk_imhtml_clear(imhtml) \ + gtk_imhtml_delete(imhtml, NULL, NULL) /** * Scrolls a GTK+ IM/HTML up by one page.