Skip to content

Commit

Permalink
Fix tkinter focus issues on Windows (#535).
Browse files Browse the repository at this point in the history
  • Loading branch information
cztomczak committed Jan 12, 2020
1 parent 8f1484c commit b7f25aa
Showing 1 changed file with 6 additions and 7 deletions.
13 changes: 6 additions & 7 deletions examples/tkinter_.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# Known issue on Linux: When typing url, mouse must be over url
# entry widget otherwise keyboard focus is lost (Issue #255
# and Issue #284).
# Other focus issues discussed in Issue #535.


from cefpython3 import cefpython as cef
import ctypes
Expand Down Expand Up @@ -153,6 +155,7 @@ def __init__(self, master, navigation_bar=None):
self.bind("<FocusIn>", self.on_focus_in)
self.bind("<FocusOut>", self.on_focus_out)
self.bind("<Configure>", self.on_configure)
"""For focus problems see Issue #255 and Issue #535. """
self.focus_set()

def embed_browser(self):
Expand Down Expand Up @@ -216,8 +219,6 @@ def on_focus_in(self, _):

def on_focus_out(self, _):
logger.debug("BrowserFrame.on_focus_out")
if self.browser:
self.browser.SetFocus(False)

def on_root_close(self):
if self.browser:
Expand All @@ -242,6 +243,7 @@ def OnLoadStart(self, browser, **_):


class FocusHandler(object):
"""For focus problems see Issue #255 and Issue #535. """

def __init__(self, browser_frame):
self.browser_frame = browser_frame
Expand All @@ -253,13 +255,10 @@ def OnTakeFocus(self, next_component, **_):
def OnSetFocus(self, source, **_):
logger.debug("FocusHandler.OnSetFocus, source={source}"
.format(source=source))
return False
return True

def OnGotFocus(self, **_):
"""Fix CEF focus issues (#255). Call browser frame's focus_set
to get rid of type cursor in url entry widget."""
logger.debug("FocusHandler.OnGotFocus")
self.browser_frame.focus_set()


class NavigationBar(tk.Frame):
Expand Down Expand Up @@ -340,7 +339,7 @@ def on_load_url(self, _):
self.master.get_browser().LoadUrl(self.url_entry.get())

def on_button1(self, _):
"""Fix CEF focus issues (#255). See also FocusHandler.OnGotFocus."""
"""For focus problems see Issue #255 and Issue #535. """
logger.debug("NavigationBar.on_button1")
self.master.master.focus_force()

Expand Down

3 comments on commit b7f25aa

@GiovaLomba
Copy link
Contributor

@GiovaLomba GiovaLomba commented on b7f25aa Jan 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To fix the tkinter example above I've successfully used an idiom that does not involve the direct use of FocusHandler callbacks.

I'll show a code sample here so that you can see if it better fits in the context of this issue

   def __init__(self) -> None:
      # To assign focus
      self.bind_all('<Button-1>', self.on_click)
      ...

   def on_click(self, event: Opt[Event]) -> None:
      # Tells the browser it has lost focus
      self._browser.SendFocusEvent(False)
      # Tells the clicked widget it has received focus
      if event.widget: 
         event.widget.focus_force()

Other types of event may be handled the same way. For instance <Button-2> for scroll or <Button-3> for context menus.

I' didn't tested code like the one above on all platforms, but if the portability of tkinter holds (as I strongly believe), the code will work seamlessly on all tkinter supported platforms.

@cztomczak
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whichever solution works, is fine. If you think your works better feel free to send PR. But it needs to be tested on all platforms.

@GiovaLomba
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many thanks for your answer and for your outstanding work. When I'll have all set I'll test the solution on all supported platforms and in case I'll send the PR.

Please sign in to comment.