10000 [3.7] bpo-39885: Make IDLE context menu cut and copy work again (GH-18951) by miss-islington · Pull Request #20524 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

[3.7] bpo-39885: Make IDLE context menu cut and copy work again (GH-18951) #20524

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Lib/idlelib/NEWS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ Released on 2020-03-10
bpo-27115: For 'Go to Line', use a Query entry box subclass with
IDLE standard behavior and improved error checking.

bpo-39885: Since clicking to get an IDLE context menu moves the
cursor, any text selection should be and now is cleared.
bpo-39885: When a context menu is invoked by right-clicking outside
of a selection, clear the selection and move the cursor. Cut and
Copy require that the click be within the selection.

bpo-39852: Edit "Go to line" now clears any selection, preventing
accidental deletion. It also updates Ln and Col on the status bar.
Expand Down
15 changes: 11 additions & 4 deletions Lib/idlelib/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,15 +499,23 @@ def handle_yview(self, event, *args):
rmenu = None

def right_menu_event(self, event):
self.text.tag_remove("sel", "1.0", "end")
self.text.mark_set("insert", "@%d,%d" % (event.x, event.y))
text = self.text
newdex = text.index(f'@{event.x},{event.y}')
try:
in_selection = (text.compare('sel.first', '<=', newdex) and
text.compare(newdex, '<=', 'sel.last'))
except TclError:
in_selection = False
if not in_selection:
text.tag_remove("sel", "1.0", "end")
text.mark_set("insert", newdex)
if not self.rmenu:
self.make_rmenu()
rmenu = self.rmenu
self.event = event
iswin = sys.platform[:3] == 'win'
if iswin:
self.text.config(cursor="arrow")
text.config(cursor="arrow")

for item in self.rmenu_specs:
try:
Expand All @@ -520,7 +528,6 @@ def right_menu_event(self, event):
state = getattr(self, verify_state)()
rmenu.entryconfigure(label, state=state)


rmenu.tk_popup(event.x_root, event.y_root)
if iswin:
self.text.config(cursor="ibeam")
Expand Down
46 changes: 36 additions & 10 deletions Lib/idlelib/idle_test/test_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from collections import namedtuple
from test.support import requires
from tkinter import Tk
from idlelib.idle_test.mock_idle import Func

Editor = editor.EditorWindow

Expand Down Expand Up @@ -92,6 +93,12 @@ def test_tabwidth_8(self):
)


def insert(text, string):
text.delete('1.0', 'end')
text.insert('end', string)
text.update() # Force update for colorizer to finish.


class IndentAndNewlineTest(unittest.TestCase):

@classmethod
Expand All @@ -113,13 +120,6 @@ def tearDownClass(cls):
cls.root.destroy()
del cls.root

def insert(self, text):
t = self.window.text
t.delete('1.0', 'end')
t.insert('end', text)
# Force update for colorizer to finish.
t.update()

def test_indent_and_newline_event(self):
eq = self.assertEqual
w = self.window
Expand Down Expand Up @@ -170,25 +170,51 @@ def test_indent_and_newline_event(self):
w.prompt_last_line = ''
for test in tests:
with self.subTest(label=test.label):
self.insert(test.text)
insert(text, test.text)
text.mark_set('insert', test.mark)
nl(event=None)
eq(get('1.0', 'end'), test.expected)

# Selected text.
self.insert(' def f1(self, a, b):\n return a + b')
insert(text, ' def f1(self, a, b):\n return a + b')
text.tag_add('sel', '1.17', '1.end')
nl(None)
# Deletes selected text before adding new line.
eq(get('1.0', 'end'), ' def f1(self, a,\n \n return a + b\n')

# Preserves the whitespace in shell prompt.
w.prompt_last_line = '>>> '
self.insert('>>> \t\ta =')
insert(text, '>>> \t\ta =')
text.mark_set('insert', '1.5')
nl(None)
eq(get('1.0', 'end'), '>>> \na =\n')


class RMenuTest(unittest.TestCase):

@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
cls.window = Editor(root=cls.root)

@classmethod
def tearDownClass(cls):
cls.window._close()
del cls.window
cls.root.update_idletasks()
for id in cls.root.tk.call('after', 'info'):
cls.root.after_cancel(id)
cls.root.destroy()
del cls.root

class DummyRMenu:
def tk_popup(x, y): pass

def test_rclick(self):
pass


if __name__ == '__main__':
unittest.main(verbosity=2)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Make context menu Cut and Copy work again when right-clicking within a
selection.
0