diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 0257de63067003..02912189465659 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -1955,6 +1955,37 @@ Base and mixin classes color change when the mouse passes over a slider). Return the resulting setting. + .. method:: tk_appname(name=None) + + Query or set the name used to communicate with this application through + the ``send`` command. + With no argument, return the current name; otherwise change it to *name* + and return the actual name set, which may have a suffix appended to keep + it unique among the applications on the display. + + .. versionadded:: next + + .. method:: tk_useinputmethods(boolean=None, *, displayof=0) + + Query or set whether Tk uses the X Input Methods (XIM) for filtering + events, and return the resulting state. + This is significant only on X11; if XIM support is not available it + always returns ``False``. + + .. versionadded:: next + + .. method:: tk_caret(*, x=None, y=None, height=None) + + Set or query the caret location for the widget's display. + The caret is the per-display insertion position used for global focus + indication (for accessibility) and for placing the input method + (XIM or IME) window. + With no argument, return the current location as a dictionary with the + keys ``'x'``, ``'y'`` and ``'height'``; otherwise update the given + coordinates. + + .. versionadded:: next + .. method:: tk_scaling(number=None, *, displayof=0) Query or set the scaling factor used by Tk to convert between physical diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index b50a43f08b5dec..c5d73ede9224ff 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -194,6 +194,12 @@ tkinter badge) and :meth:`~tkinter.Wm.wm_stackorder` (toplevel stacking order). (Contributed by Serhiy Storchaka in :gh:`151874`.) +* Added the :meth:`~tkinter.Misc.tk_appname`, + :meth:`~tkinter.Misc.tk_useinputmethods` and :meth:`~tkinter.Misc.tk_caret` + methods, exposing the application send name, the X Input Methods state and + the input method caret location. + (Contributed by Serhiy Storchaka in :gh:`151886`.) + * Added support for more options in :class:`!tkinter.PhotoImage` methods: the *format* parameter of :meth:`~tkinter.PhotoImage.put`, the *metadata* parameter of :meth:`~tkinter.PhotoImage.put`, :meth:`~tkinter.PhotoImage.read`, diff --git a/Lib/test/test_tkinter/test_misc.py b/Lib/test/test_tkinter/test_misc.py index 80dc163fc18de4..15239efd83904f 100644 --- a/Lib/test/test_tkinter/test_misc.py +++ b/Lib/test/test_tkinter/test_misc.py @@ -463,6 +463,29 @@ def test_tk_bisque(self): self.assertEqual(root['background'], '#ffe4c4') self.assertRaises(TypeError, root.tk_bisque, 'x') + def test_tk_appname(self): + old = self.root.tk_appname() + self.assertIsInstance(old, str) + self.addCleanup(self.root.tk_appname, old) + # Setting the name returns the actual name (possibly with a suffix + # appended to keep it unique). + new = self.root.tk_appname('PythonTkTest') + self.assertIsInstance(new, str) + self.assertEqual(self.root.tk_appname(), new) + + def test_tk_useinputmethods(self): + old = self.root.tk_useinputmethods() + self.assertIsInstance(old, bool) + self.addCleanup(self.root.tk_useinputmethods, old) + # Setting returns the resulting state. On systems without XIM support + # the state is always False, so only check the True->False direction. + self.assertIs(self.root.tk_useinputmethods(False), False) + + def test_tk_caret(self): + self.assertIsNone(self.root.tk_caret(x=5, y=10, height=20)) + caret = self.root.tk_caret() + self.assertEqual(caret, {'x': 5, 'y': 10, 'height': 20}) + def test_tk_scaling(self): old = self.root.tk_scaling() self.assertIsInstance(old, float) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index dd7407176ddd8f..b1015d2d5d0c23 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -745,6 +745,47 @@ def tk_setPalette(self, *args, **kw): self.tk.call(('tk_setPalette',) + _flatten(args) + _flatten(list(kw.items()))) + def tk_appname(self, name=None): + """Query or set the name used to communicate with this application + through the send command. + + With no argument, return the current name; otherwise change it to NAME + and return the actual name set (which may have a suffix appended to + keep it unique).""" + if name is None: + return self.tk.call('tk', 'appname') + return self.tk.call('tk', 'appname', name) + + def tk_useinputmethods(self, boolean=None, *, displayof=0): + """Query or set whether Tk uses the X Input Methods (XIM) for filtering + events, and return the resulting state. + + This is significant only on X11; if XIM support is not available it + always returns False.""" + args = ('tk', 'useinputmethods') + self._displayof(displayof) + if boolean is not None: + args += (boolean,) + return self.tk.getboolean(self.tk.call(args)) + + def tk_caret(self, *, x=None, y=None, height=None): + """Set or query the caret location for this widget's display. + + The caret is the per-display insertion position used for global focus + indication (for accessibility) and for placing the input method + (XIM or IME) window. With no argument, return the current location as + a dictionary with keys 'x', 'y' and 'height'; otherwise update the + given coordinates.""" + args = ('tk', 'caret', self._w) + for option, value in (('-x', x), ('-y', y), ('-height', height)): + if value is not None: + args += (option, value) + if len(args) > 3: + self.tk.call(args) + else: + values = self.tk.splitlist(self.tk.call(args)) + return {values[i][1:]: self.tk.getint(values[i + 1]) + for i in range(0, len(values), 2)} + def tk_scaling(self, number=None, *, displayof=0): """Query or set the scaling factor used by Tk to convert between physical units and pixels. diff --git a/Misc/NEWS.d/next/Library/2026-06-22-01-51-06.gh-issue-151886.MsLlNz.rst b/Misc/NEWS.d/next/Library/2026-06-22-01-51-06.gh-issue-151886.MsLlNz.rst new file mode 100644 index 00000000000000..7a454ab95f371f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-22-01-51-06.gh-issue-151886.MsLlNz.rst @@ -0,0 +1,4 @@ +Add the :meth:`!tkinter.Misc.tk_appname`, +:meth:`!tkinter.Misc.tk_useinputmethods` and :meth:`!tkinter.Misc.tk_caret` +methods, wrapping the ``tk appname``, ``tk useinputmethods`` and ``tk caret`` +Tk commands.