- GdkRectangle rectangle, cursor_rectangle;
- GtkTextIter position;
- gboolean visible;
- gint cursor_bottom;
-
- /* We detect if cursor is visible using the full height, not only the center. This
- seems to work */
- gtk_text_view_get_visible_rect (GTK_TEXT_VIEW (priv->msg_body), &rectangle);
- gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer),
- &position,
- gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer)));
- gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &position, &cursor_rectangle);
-
- cursor_bottom = (cursor_rectangle.y + cursor_rectangle.height);
- visible = (cursor_rectangle.y >= rectangle.y) && (cursor_bottom < (rectangle.y + rectangle.height));
-
- if (gtk_widget_is_focus (priv->msg_body) &&
- !visible) {
- if (priv->last_vadj_upper != adj->upper) {
- GtkTextMark *insert;
-
- insert = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
- gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (priv->msg_body),
- insert, 0.1, FALSE, 0.0, 0.0);
+gboolean
+scroll_drag_timeout (gpointer userdata)
+{
+ ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
+ ModestMsgEditWindowPrivate *priv;
+
+ priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
+
+ correct_scroll_without_drag_check (win);
+
+ priv->scroll_drag_timeout_id = 0;
+
+ return FALSE;
+}
+
+static void
+correct_scroll_without_drag_check (ModestMsgEditWindow *w)
+{
+ ModestMsgEditWindowPrivate *priv;
+ GtkTextMark *insert;
+ GtkTextIter iter;
+ GdkRectangle rectangle;
+ GtkAdjustment *vadj;
+ gdouble new_value;
+ gint offset;
+ GdkWindow *window;
+
+ priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
+
+ insert = gtk_text_buffer_get_insert (priv->text_buffer);
+ gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
+
+ gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
+ vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll));
+ offset = priv->msg_body->allocation.y;
+
+ new_value = vadj->value;
+
+ if ((offset + rectangle.y + rectangle.height) >
+ ((gint) (vadj->value +vadj->page_size))) {
+ new_value = (offset + rectangle.y) + vadj->page_size * 0.75;
+ if (new_value > vadj->upper - vadj->page_size)
+ new_value = vadj->upper - vadj->page_size;
+ } else if ((offset + rectangle.y) < ((gint) vadj->value)) {
+ new_value = (offset + rectangle.y - vadj->page_size * 0.75);
+ if (((gint) (new_value + vadj->page_size)) < (offset + rectangle.y + rectangle.height))
+ new_value = offset + rectangle.y + rectangle.height - (gint) vadj->page_size;
+ if (new_value < 0.0)
+ new_value = 0.0;
+ if (new_value > vadj->value)
+ new_value = vadj->value;
+ }
+
+ if (vadj->value != new_value) {
+ g_signal_emit_by_name (GTK_TEXT_VIEW(priv->msg_body)->layout,
+ "invalidated");
+ vadj->value = new_value;
+ gtk_adjustment_value_changed (vadj);
+ /* invalidate body */
+ window = gtk_widget_get_parent_window (priv->msg_body);
+ if (window)
+ gdk_window_invalidate_rect (window, NULL, TRUE);
+ }
+
+}
+
+static void
+correct_scroll (ModestMsgEditWindow *w)
+{
+ ModestMsgEditWindowPrivate *priv;
+
+ priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
+ if (gtk_grab_get_current () == priv->msg_body) {
+ if (priv->scroll_drag_timeout_id == 0) {
+ priv->scroll_drag_timeout_id = g_timeout_add (500, (GSourceFunc) scroll_drag_timeout,
+ (gpointer) w);