Merge lp:~brandontschaefer/unity/unity.fix-middle-paste-reg into lp:unity

Proposed by Brandon Schaefer
Status: Merged
Approved by: Brandon Schaefer
Approved revision: no longer in the source branch.
Merged at revision: 2017
Proposed branch: lp:~brandontschaefer/unity/unity.fix-middle-paste-reg
Merge into: lp:unity
Diff against target: 174 lines (+115/-4)
3 files modified
plugins/unityshell/src/IMTextEntry.cpp (+14/-4)
plugins/unityshell/src/IMTextEntry.h (+2/-0)
tests/autopilot/autopilot/tests/test_dash.py (+99/-0)
To merge this branch: bzr merge lp:~brandontschaefer/unity/unity.fix-middle-paste-reg
Reviewer Review Type Date Requested Status
Thomi Richards (community) Approve
Tim Penhey (community) Needs Information
Review via email: mp+94441@code.launchpad.net

Description of the change

= Problem description =

Fixes middle mouse button pasting, which was removed by me.

= The fix =

Restored the IMTextEntry::OnMouseButtonUp function but now it only handles paste with the middle mouse

= Test coverage =

There is a manual test for this

To post a comment you must log in.
Revision history for this message
Tim Penhey (thumper) wrote :

I've edited the description to use our new template.

Can you update the fix and test coverage section please?

review: Needs Information
Revision history for this message
Thomi Richards (thomir-deactivatedaccount) wrote :
Download full text (3.3 KiB)

Hi,

First, the standard for clipboard is here: http://www.freedesktop.org/wiki/Specifications/ClipboardsWiki?action=show&redirect=Standards%2FClipboardsWiki

The PRIMARY clipboard should be set when the MOUSE selects some text, and should be pasted on MOUSE middle-click ONLY.
The CLIPBOARD clipboard is used for menu entries, and Ctrl+[cxv] shortcuts.

Regarding your first test:

50 + def test_paste_crash(self):
51 + """ This test is for this bug:926793 """
52 + self.dash.ensure_hidden()
53 + self.dash.toggle_reveal()
54 +
55 + kb = Keyboard();
56 + kb.type("SegFault")
57 + sleep(1)
58 +
59 + kb.press_and_release("Ctrl+a")
60 + kb.press_and_release("Ctrl+c")
61 + kb.press_and_release("Ctrl+v")
62 +
63 + searchbar = self.dash.get_searchbar()
64 + self.assertEqual(searchbar.search_string, u'SegFault')

This needs to be fixed, for a couple of reasons. First, we don't have a test that verifies that Ctrl+a works. So your test should be something like this:

50 + def test_paste_crash(self):
51 + """ This test is for this bug:926793 """
52 + self.dash.ensure_hidden()
53 + self.dash.toggle_reveal()
54 +
55 + kb = Keyboard();
56 + kb.type("SegFault")
57 + sleep(1)
58 +
59 + kb.press_and_release("Ctrl+a")
   kb.press_and_release("Delete")
63 + searchbar = self.dash.get_searchbar()
64 + self.assertEqual(searchbar.search_string, u'')

Secondly, you need to verify that Ctrl+C actually does something. If both Ctrl+C and Ctrl+V stopped working, your test would still pass. So how about somethingt like this:

50 + def test_paste_crash(self):
51 + """ This test is for this bug:926793 """
52 + self.dash.ensure_hidden()
53 + self.dash.toggle_reveal()
54 +
55 + kb = Keyboard();
56 + kb.type("SegFault")
57 + sleep(1)
58 +
59 + kb.press_and_release("Ctrl+a")
60 + kb.press_and_release("Ctrl+c")
60 + kb.press_and_release("Ctrl+v")
60 + kb.press_and_release("Ctrl+v")
62 +
63 + searchbar = self.dash.get_searchbar()
64 + self.assertEqual(searchbar.search_string, u'SegFaultSegfault')

We also need to test Ctrl+x (I assume we're supposed to support that):

50 + def test_paste_crash(self):
51 + """ This test is for this bug:926793 """
52 + self.dash.ensure_hidden()
53 + self.dash.toggle_reveal()
54 +
55 + kb = Keyboard();
56 + kb.type("SegFault")
57 + sleep(1)
58 +
59 + kb.press_and_release("Ctrl+a")
60 + kb.press_and_release("Ctrl+x")
62 +
63 + searchbar = self.dash.get_searchbar()
64 + self.assertEqual(searchbar.search_string, u'')

...and also:

50 + def test_paste_crash(self):
51 + """ This test is for this bug:926793 """
52 + self.dash.ensure_hidden()
53 + self.dash.toggle_reveal()
54 +
55 + kb = Keyboard();
56 + kb.type("SegFault")
57 + sleep(1)
58 +
59 + kb.press_and_release("Ctrl+a")
60 + kb.press_and_release("Ctrl+x")
60 + kb.press_and_release("Ctrl+v")
60 + kb.press_and_release("Ctrl+v")
62 +
63 + searchbar = self.dash.get_searchbar()
64 + self.assertEqual(searchbar.search_string, u'SegFaultSegfault')

Finally, we need to do something similar with the PRIMARY clipboard.

You can put something onto the clipboard artificiall with this code:

from gtk import Clipboard
cb = Clipboard(selection="PRIMARY") # can also be "CLIPBOARD", but we can test that easily enough a...

Read more...

review: Needs Fixing
Revision history for this message
Thomi Richards (thomir-deactivatedaccount) wrote :

Looks great.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unityshell/src/IMTextEntry.cpp'
2--- plugins/unityshell/src/IMTextEntry.cpp 2012-02-23 10:12:51 +0000
3+++ plugins/unityshell/src/IMTextEntry.cpp 2012-02-24 03:10:23 +0000
4@@ -37,6 +37,7 @@
5 IMTextEntry::IMTextEntry()
6 : TextEntry("", NUX_TRACKER_LOCATION)
7 {
8+ mouse_up.connect(sigc::mem_fun(this, &IMTextEntry::OnMouseButtonUp));
9 }
10
11 bool IMTextEntry::InspectKeyEvent(unsigned int event_type,
12@@ -104,8 +105,7 @@
13 int start=0, end=0;
14 if (GetSelectionBounds(&start, &end))
15 {
16- GtkClipboard* clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
17- GDK_SELECTION_CLIPBOARD);
18+ GtkClipboard* clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
19 gtk_clipboard_set_text(clip, text_.c_str() + start, end - start);
20 }
21 }
22@@ -113,8 +113,7 @@
23 void IMTextEntry::Paste(bool primary)
24 {
25 GdkAtom origin = primary ? GDK_SELECTION_PRIMARY : GDK_SELECTION_CLIPBOARD;
26- glib::Object<GtkClipboard> clip(gtk_clipboard_get_for_display(gdk_display_get_default(),
27- origin));
28+ GtkClipboard* clip = gtk_clipboard_get(origin);
29
30 auto callback = [](GtkClipboard* clip, const char* text, gpointer user_data)
31 {
32@@ -142,4 +141,15 @@
33 text_changed.emit(this);
34 }
35 }
36+
37+void IMTextEntry::OnMouseButtonUp(int x, int y, unsigned long bflags, unsigned long kflags)
38+{
39+ int button = nux::GetEventButton(bflags);
40+
41+ if (button == 2)
42+ {
43+ SetCursor(XYToTextIndex(x,y));
44+ Paste(true);
45+ }
46+}
47 }
48
49=== modified file 'plugins/unityshell/src/IMTextEntry.h'
50--- plugins/unityshell/src/IMTextEntry.h 2012-02-23 05:16:50 +0000
51+++ plugins/unityshell/src/IMTextEntry.h 2012-02-24 03:10:23 +0000
52@@ -47,6 +47,8 @@
53 void Cut();
54 void Copy();
55 void Paste(bool primary = false);
56+
57+ void OnMouseButtonUp(int x, int y, unsigned long bflags, unsigned long kflags);
58 };
59
60 }
61
62=== modified file 'tests/autopilot/autopilot/tests/test_dash.py'
63--- tests/autopilot/autopilot/tests/test_dash.py 2012-02-23 02:20:09 +0000
64+++ tests/autopilot/autopilot/tests/test_dash.py 2012-02-24 03:10:23 +0000
65@@ -13,6 +13,8 @@
66 from autopilot.tests import AutopilotTestCase
67 from autopilot.glibrunner import GlibRunner
68
69+from gtk import Clipboard
70+
71
72 class DashRevealTests(AutopilotTestCase):
73 """Test the unity Dash Reveal."""
74@@ -265,3 +267,100 @@
75 kb.press_and_release('Tab')
76 category = app_lens.get_focused_category()
77 self.assertIsNot(category, None)
78+
79+class DashClipboardTests(AutopilotTestCase):
80+ """Test the Unity clipboard"""
81+ run_test_with = GlibRunner
82+
83+ def setUp(self):
84+ super(DashClipboardTests, self).setUp()
85+ self.dash = Dash()
86+
87+ def tearDown(self):
88+ super(DashClipboardTests, self).tearDown()
89+ self.dash.ensure_hidden()
90+
91+ def test_ctrl_a(self):
92+ """ This test if ctrl+a selects all text """
93+ self.dash.ensure_hidden()
94+ self.dash.toggle_reveal()
95+
96+ kb = Keyboard();
97+ kb.type("SelectAll")
98+ sleep(1)
99+
100+ kb.press_and_release("Ctrl+a")
101+ kb.press_and_release("Delete")
102+
103+ searchbar = self.dash.get_searchbar()
104+ self.assertEqual(searchbar.search_string, u'')
105+
106+ def test_ctrl_c(self):
107+ """ This test if ctrl+c copies text into the clipboard """
108+ self.dash.ensure_hidden()
109+ self.dash.toggle_reveal()
110+
111+ kb = Keyboard();
112+ kb.type("Copy")
113+ sleep(1)
114+
115+ kb.press_and_release("Ctrl+a")
116+ kb.press_and_release("Ctrl+c")
117+
118+ cb = Clipboard(selection="CLIPBOARD")
119+
120+ searchbar = self.dash.get_searchbar()
121+ self.assertEqual(searchbar.search_string, cb.wait_for_text())
122+
123+ def test_ctrl_x(self):
124+ """ This test if ctrl+x deletes all text and copys it """
125+ self.dash.ensure_hidden()
126+ self.dash.toggle_reveal()
127+
128+ kb = Keyboard();
129+ kb.type("Cut")
130+ sleep(1)
131+
132+ kb.press_and_release("Ctrl+a")
133+ kb.press_and_release("Ctrl+x")
134+ sleep(1)
135+
136+ searchbar = self.dash.get_searchbar()
137+ self.assertEqual(searchbar.search_string, u'')
138+
139+ cb = Clipboard(selection="CLIPBOARD")
140+ self.assertEqual(cb.wait_for_text(), u'Cut')
141+
142+ def test_ctrl_c_v(self):
143+ """ This test if ctrl+c and ctrl+v copies and pastes text"""
144+ self.dash.ensure_hidden()
145+ self.dash.toggle_reveal()
146+
147+ kb = Keyboard();
148+ kb.type("CopyPaste")
149+ sleep(1)
150+
151+ kb.press_and_release("Ctrl+a")
152+ kb.press_and_release("Ctrl+c")
153+ kb.press_and_release("Ctrl+v")
154+ kb.press_and_release("Ctrl+v")
155+
156+ searchbar = self.dash.get_searchbar()
157+ self.assertEqual(searchbar.search_string, u'CopyPasteCopyPaste')
158+
159+ def test_ctrl_x_v(self):
160+ """ This test if ctrl+x and ctrl+v cuts and pastes text"""
161+ self.dash.ensure_hidden()
162+ self.dash.toggle_reveal()
163+
164+ kb = Keyboard();
165+ kb.type("CutPaste")
166+ sleep(1)
167+
168+ kb.press_and_release("Ctrl+a")
169+ kb.press_and_release("Ctrl+x")
170+ kb.press_and_release("Ctrl+v")
171+ kb.press_and_release("Ctrl+v")
172+
173+ searchbar = self.dash.get_searchbar()
174+ self.assertEqual(searchbar.search_string, u'CutPasteCutPaste')