Package: gnome-shell
Version: 3.30.2-7
Severity: important
Tags: upstream patch fixed-upstream
Forwarded: https://gitlab.gnome.org/GNOME/gtk/issues/1447

There is a bad interaction between gnome-shell, GTK, non-English input
methods, WebKitGTK and Evolution that can cause text to be deleted
unintentionally. I have not verified whether Debian is still affected by
this (it's a tricky interaction between several components, and multiple
workarounds and fixes have been applied upstream, some of which might
already be in buster) but there is a patch for gnome-shell in upstream's
gnome-3-30 branch, which I think we should consider applying for buster
to try to rule out data loss.

https://gitlab.gnome.org/GNOME/gtk/issues/1447:
> evolution-3.30.2-2.fc29.x86_64; webkit2gtk3-2.22.3-1.fc29.x86_64
> Steps:
>
> Enable: Edit > Preferences > Mail Preferences > HTML Messages >
>  Plain Text Mode > Show suppressed HTML parts as attachments.
> Disable: Edit > Preferences > Composer Preferences > Default Behavior >
>  Format messages in HTML
> Open 
> https://mail.gnome.org/archives/evolution-list/2018-November/msg00023.html
> Press Ctrl+L (reply)
> Mark any lines of text in the email
> Press the Ctrl key
>
> Expected outcome: Nothing
>
> Actual outcome: The marked text get deleted.

See attached patches (untested).

    smcv
>From 401062800186ca26135d270f2285d8b2b5446437 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carl...@gnome.org>
Date: Tue, 13 Nov 2018 18:26:13 +0100
Subject: [PATCH 1/2] inputMethod: Avoid calling set_preedit_text() if
 unnecessary

This is easier down on clients.

(cherry-picked from 8c3811a866017943c276fa7d9e2aed4c0f0554ae)
---
 js/misc/inputMethod.js | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/js/misc/inputMethod.js b/js/misc/inputMethod.js
index 4a92dc49b..e22dfccc5 100644
--- a/js/misc/inputMethod.js
+++ b/js/misc/inputMethod.js
@@ -144,8 +144,11 @@ var InputMethod = new Lang.Class({
             this._updateCapabilities();
         }
 
-        // Unset any preedit text
-        this.set_preedit_text(null, 0);
+        if (this._preeditStr) {
+            // Unset any preedit text
+            this.set_preedit_text(null, 0);
+            this._preeditStr = null;
+        }
     },
 
     vfunc_reset() {
@@ -154,8 +157,11 @@ var InputMethod = new Lang.Class({
             this._emitRequestSurrounding();
         }
 
-        // Unset any preedit text
-        this.set_preedit_text(null, 0);
+        if (this._preeditStr) {
+            // Unset any preedit text
+            this.set_preedit_text(null, 0);
+            this._preeditStr = null;
+        }
     },
 
     vfunc_set_cursor_location(rect) {
-- 
2.20.1

>From 1cda65973272baff218244e69dca0afc329ba6da Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carl...@gnome.org>
Date: Tue, 13 Nov 2018 18:28:15 +0100
Subject: [PATCH 2/2] inputMethod: Keep track of preedit string visibility

So we can silence update-preedit-text signals that keep the
preedit string invisible.

Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1447

(cherry-picked from 6f5a099184a1a5ecf558b36f2d00d2bfb074628e)
---
 js/misc/inputMethod.js | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/js/misc/inputMethod.js b/js/misc/inputMethod.js
index e22dfccc5..0f5590b3f 100644
--- a/js/misc/inputMethod.js
+++ b/js/misc/inputMethod.js
@@ -17,6 +17,7 @@ var InputMethod = new Lang.Class({
         this._currentFocus = null;
         this._preeditStr = '';
         this._preeditPos = 0;
+        this._preeditVisible = false;
         this._ibus = IBus.Bus.new_async();
         this._ibus.connect('connected', this._onConnected.bind(this));
         this._ibus.connect('disconnected', this._clear.bind(this));
@@ -80,6 +81,7 @@ var InputMethod = new Lang.Class({
         this._enabled = false;
         this._preeditStr = ''
         this._preeditPos = 0;
+        this._preeditVisible = false;
     },
 
     _emitRequestSurrounding() {
@@ -98,20 +100,27 @@ var InputMethod = new Lang.Class({
     _onUpdatePreeditText(context, text, pos, visible) {
         if (text == null)
             return;
-        this._preeditStr = text.get_text();
-        this._preeditPos = pos;
+
+        let preedit = text.get_text();
+
         if (visible)
-            this.set_preedit_text(this._preeditStr, pos);
-        else
+            this.set_preedit_text(preedit, pos);
+        else if (this._preeditVisible)
             this.set_preedit_text(null, pos);
+
+        this._preeditStr = preedit;
+        this._preeditPos = pos;
+        this._preeditVisible = visible;
     },
 
     _onShowPreeditText(context) {
+        this._preeditVisible = true;
         this.set_preedit_text(this._preeditStr, this._preeditPos);
     },
 
     _onHidePreeditText(context) {
         this.set_preedit_text(null, this._preeditPos);
+        this._preeditVisible = false;
     },
 
     _onForwardKeyEvent(context, keyval, keycode, state) {
-- 
2.20.1

Reply via email to