]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-151886: Add tkinter Misc.tk_appname, tk_useinputmethods and tk_caret (GH-151887)
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 22 Jun 2026 17:31:25 +0000 (20:31 +0300)
committerGitHub <noreply@github.com>
Mon, 22 Jun 2026 17:31:25 +0000 (17:31 +0000)
Wrap three long-standing Tk commands that had no tkinter wrapper:

* Misc.tk_appname() queries or sets the name used to communicate with the
  application through the send command (Tk 8.5).
* Misc.tk_useinputmethods() queries or sets whether Tk uses the X Input
  Methods (XIM) for filtering events (Tk 8.5).
* Misc.tk_caret() sets or queries the per-display caret location used for
  accessibility and for placing the input method window (Tk 8.5).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Doc/library/tkinter.rst
Doc/whatsnew/3.16.rst
Lib/test/test_tkinter/test_misc.py
Lib/tkinter/__init__.py
Misc/NEWS.d/next/Library/2026-06-22-01-51-06.gh-issue-151886.MsLlNz.rst [new file with mode: 0644]

index 0257de630670033903845704f0f9f8aac97c28eb..029121894656592c746d63d7c5656ec2298afcf9 100644 (file)
@@ -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
index b50a43f08b5dec8099d3fe606bdf66c9a2479aa8..c5d73ede9224ff56e969a411065eb8e4b08b71f9 100644 (file)
@@ -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`,
index 80dc163fc18de412158cb014d7e1738075d7706b..15239efd83904fdb2a61329847299b6e41eb2fda 100644 (file)
@@ -463,6 +463,29 @@ class MiscTest(AbstractTkTest, unittest.TestCase):
         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)
index dd7407176ddd8f984698858fb6c146c3ea7723b9..b1015d2d5d0c23f1aec353e96c3b6f8f73830ffa 100644 (file)
@@ -745,6 +745,47 @@ class Misc:
         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 (file)
index 0000000..7a454ab
--- /dev/null
@@ -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.