Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

bindglobal

bindglobal is a python-tkinter-bind alike, but run for system-wide global desktop: Windows, Linux (Xorg) and MacOS enviroments. It is based on pynput

You can easily define callbacks for mouse & keystrokes events, or any combination of them.

Follow instructions in python tkinter bind or tk bind documentation for definition of keyboard&mouse combinations.

In addition to bind, bindglobal add:

'<Idle>' to discover user inactivity based on no keyboard and mouse events

'<Long->' to get Long pressing of keys and buttons (not yet avaliable)

How to use

Install

with pip install bindglobal

Code

The minimum example, import, define callback functions, create a BindGlobal object, and bind combinations to callbaks.

from bindglobal import BindGlobal
def callback(event): print("running callback in another thread. Event=" + str(event)) def exit(event): print('exiting')
bg.stop()
bg = BindGlobal()
bg.bind("<Menu-1>",callback) bg.bind("<Triple-Escape>",exit) 

callback will be run in a separate thread every time you press [Menu key] + [Button1] mouse (left clic), simultaneously. exit will be called when triple-press [Esc] key.

Inportant notes:

  • Callbacks can not take long time to be executed, so other binding calls will be queued.

  • Keyrelease modifier apply to all keys in combination definition. I.e. <'Control-KeyRelease-z'> will fire when all ([Control]-key and [z]-key) are released (after they has been simultaneously pressed)

Working modes

Callbacks can run asynchronously from main thread by two diferent aproach:

Threaded mode (default)

All binding callbacks run on a (only-one for all bindings) separate thread. Note that its your responsability to manage thread-safe interations with your main-thread (I.e. you cant call tkinter gui from inside callback). At least 4 threads will be running:

  1. main-thread
  2. and 3. keyboard-listener-thread and mouse-listener-thread (from pynput)
  3. callbacks-thread

Tkinter mode

All binding callbacks will be launched from tkinter main-loop (with tkinter event generation), so callbacks will be runnig in main-thread (you can safely call tkinter gui from inside callback). To enable this mode you have to provide a tkinter widget when init BindGlobal class:

root = tkinter.Tk() bg = BindGlobal(widget=root)

Please, note than more than one BindGlobal object can be created (every object with their own separate threads and bindings).

Methods:

bind / unbind

bg.bind(combination,callback,param) combination (or event): Combiantion string definition as standar tkinter bind command. If None, return all list of actual bindings callback: your callback funtion, that will be called everytime combination is detected. Must be defined to receive the event paratemter. if None, return actual bindings for this combination param: can be '+' to add new callbacks to same combination, or timeout seconds in '' event.

unbind works as expected tkinter unbind, removing bind callback

Examples of combinations:

'<Triple-Shift_R>': Triple clic over 'Right Shift' key

'<Double-Control_R-c>': fired when double-clic over 'c' key, while 'Right-Control' presed

Special Idle event

bg.bind('<Idle>',callback_when_idle,300)

callback_when_idle will be called when:

  • Every timeout=300 seconds with no keyboard or mouse action. Event will contain:
    • .event = '<Idle>'
    • .count = 1,2,....n (for every timeout)
  • Exit from idle mode (any keyboard or mouse event):
    • .event = '<after_idle>'
    • .count = 1

start, stop and pause

keyboard

bg.keyboard let access to internal pynput keyboard controller. In example: bg.keyboard.type("write this string")

mouse

bg.mouse let access to internal pynput mouse controller.

type

bg.keyboard.type("write this string")

Event

Bindglobal event (sended as parameter to every binded callback) follow the tkinter bind event structure:

  • event: The combination key-mouse that fire the callback, as created in bind method. '' or '<After_Idle>'
  • widget: The tkinter widget in tkinter mode or None in threaded mode
  • x, y: The current global mouse position, in pixels.
  • char: The character code (keyboard events only), as a string.
  • keysym: The key symbol (keyboard events only). Not implemented
  • keycode: The key code (keyboard events only).
  • num: The button number (mouse button events only).
  • type: The event type ('keyboard', 'mouse') that make fire the event.
  • time: datetime of last key/mouse that make fires the bind event
  • delta: mousewheel points (positve/negative
  • state: string showing modifiers keys like alt, control, shift, etc. in a 'alt_l+shift_r+' form (note this is not included in tkinter standard event)
  • count (%c): The count field from the event. In event: times the timeout has expired. In key events: the times key-pressed without key-released (repeated keys). In mouse clic-relese events, the total time in milliseconds of pressed button.

Depending on type of Pynput event however, not all attributes may be set.

Other examples:

Multiple callbacks

asociated to triple clic over 'f' key, (but launching on release):

bg.bind("<Triple-KeyRelease-f>",callback1)bg.bind("<Triple-KeyRelease-f>",callback2, '+')

Other keycodes

bg.bind("<65027>",lambda e: print("ALT-GR in LINUX"+str(e)))

Drag init (clic mouse, and movement without release)

bg.bind("<Motion-Button1>",lambda e: print("DRAG:"+str(e)))

Win+Alt key when release

bg.bind("<Command-Alt_L-KeyRelease>",lambda e: print("WIN+Alt:"+str(e)))

Press any key

bg.bind("<KeyPress>",callback5)

About

python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events)

Resources

Stars

10 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - segalion/bindglobal: python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events) · GitHub
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

bindglobal

bindglobal is a python-tkinter-bind alike, but run for system-wide global desktop: Windows, Linux (Xorg) and MacOS enviroments. It is based on pynput

You can easily define callbacks for mouse & keystrokes events, or any combination of them.

Follow instructions in python tkinter bind or tk bind documentation for definition of keyboard&mouse combinations.

In addition to bind, bindglobal add:

'<Idle>' to discover user inactivity based on no keyboard and mouse events

'<Long->' to get Long pressing of keys and buttons (not yet avaliable)

How to use

Install

with pip install bindglobal

Code

The minimum example, import, define callback functions, create a BindGlobal object, and bind combinations to callbaks.

from bindglobal import BindGlobal
def callback(event): print("running callback in another thread. Event=" + str(event)) def exit(event): print('exiting')
bg.stop()
bg = BindGlobal()
bg.bind("<Menu-1>",callback) bg.bind("<Triple-Escape>",exit) 

callback will be run in a separate thread every time you press [Menu key] + [Button1] mouse (left clic), simultaneously. exit will be called when triple-press [Esc] key.

Inportant notes:

  • Callbacks can not take long time to be executed, so other binding calls will be queued.

  • Keyrelease modifier apply to all keys in combination definition. I.e. <'Control-KeyRelease-z'> will fire when all ([Control]-key and [z]-key) are released (after they has been simultaneously pressed)

Working modes

Callbacks can run asynchronously from main thread by two diferent aproach:

Threaded mode (default)

All binding callbacks run on a (only-one for all bindings) separate thread. Note that its your responsability to manage thread-safe interations with your main-thread (I.e. you cant call tkinter gui from inside callback). At least 4 threads will be running:

  1. main-thread
  2. and 3. keyboard-listener-thread and mouse-listener-thread (from pynput)
  3. callbacks-thread

Tkinter mode

All binding callbacks will be launched from tkinter main-loop (with tkinter event generation), so callbacks will be runnig in main-thread (you can safely call tkinter gui from inside callback). To enable this mode you have to provide a tkinter widget when init BindGlobal class:

root = tkinter.Tk() bg = BindGlobal(widget=root)

Please, note than more than one BindGlobal object can be created (every object with their own separate threads and bindings).

Methods:

bind / unbind

bg.bind(combination,callback,param) combination (or event): Combiantion string definition as standar tkinter bind command. If None, return all list of actual bindings callback: your callback funtion, that will be called everytime combination is detected. Must be defined to receive the event paratemter. if None, return actual bindings for this combination param: can be '+' to add new callbacks to same combination, or timeout seconds in '' event.

unbind works as expected tkinter unbind, removing bind callback

Examples of combinations:

'<Triple-Shift_R>': Triple clic over 'Right Shift' key

'<Double-Control_R-c>': fired when double-clic over 'c' key, while 'Right-Control' presed

Special Idle event

bg.bind('<Idle>',callback_when_idle,300)

callback_when_idle will be called when:

  • Every timeout=300 seconds with no keyboard or mouse action. Event will contain:
    • .event = '<Idle>'
    • .count = 1,2,....n (for every timeout)
  • Exit from idle mode (any keyboard or mouse event):
    • .event = '<after_idle>'
    • .count = 1

start, stop and pause

keyboard

bg.keyboard let access to internal pynput keyboard controller. In example: bg.keyboard.type("write this string")

mouse

bg.mouse let access to internal pynput mouse controller.

type

bg.keyboard.type("write this string")

Event

Bindglobal event (sended as parameter to every binded callback) follow the tkinter bind event structure:

  • event: The combination key-mouse that fire the callback, as created in bind method. '' or '<After_Idle>'
  • widget: The tkinter widget in tkinter mode or None in threaded mode
  • x, y: The current global mouse position, in pixels.
  • char: The character code (keyboard events only), as a string.
  • keysym: The key symbol (keyboard events only). Not implemented
  • keycode: The key code (keyboard events only).
  • num: The button number (mouse button events only).
  • type: The event type ('keyboard', 'mouse') that make fire the event.
  • time: datetime of last key/mouse that make fires the bind event
  • delta: mousewheel points (positve/negative
  • state: string showing modifiers keys like alt, control, shift, etc. in a 'alt_l+shift_r+' form (note this is not included in tkinter standard event)
  • count (%c): The count field from the event. In event: times the timeout has expired. In key events: the times key-pressed without key-released (repeated keys). In mouse clic-relese events, the total time in milliseconds of pressed button.

Depending on type of Pynput event however, not all attributes may be set.

Other examples:

Multiple callbacks

asociated to triple clic over 'f' key, (but launching on release):

bg.bind("<Triple-KeyRelease-f>",callback1)bg.bind("<Triple-KeyRelease-f>",callback2, '+')

Other keycodes

bg.bind("<65027>",lambda e: print("ALT-GR in LINUX"+str(e)))

Drag init (clic mouse, and movement without release)

bg.bind("<Motion-Button1>",lambda e: print("DRAG:"+str(e)))

Win+Alt key when release

bg.bind("<Command-Alt_L-KeyRelease>",lambda e: print("WIN+Alt:"+str(e)))

Press any key

bg.bind("<KeyPress>",callback5)

About

python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events)

Resources

Stars

10 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - segalion/bindglobal: python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events) · GitHub
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

bindglobal

bindglobal is a python-tkinter-bind alike, but run for system-wide global desktop: Windows, Linux (Xorg) and MacOS enviroments. It is based on pynput

You can easily define callbacks for mouse & keystrokes events, or any combination of them.

Follow instructions in python tkinter bind or tk bind documentation for definition of keyboard&mouse combinations.

In addition to bind, bindglobal add:

'<Idle>' to discover user inactivity based on no keyboard and mouse events

'<Long->' to get Long pressing of keys and buttons (not yet avaliable)

How to use

Install

with pip install bindglobal

Code

The minimum example, import, define callback functions, create a BindGlobal object, and bind combinations to callbaks.

from bindglobal import BindGlobal
def callback(event): print("running callback in another thread. Event=" + str(event)) def exit(event): print('exiting')
bg.stop()
bg = BindGlobal()
bg.bind("<Menu-1>",callback) bg.bind("<Triple-Escape>",exit) 

callback will be run in a separate thread every time you press [Menu key] + [Button1] mouse (left clic), simultaneously. exit will be called when triple-press [Esc] key.

Inportant notes:

  • Callbacks can not take long time to be executed, so other binding calls will be queued.

  • Keyrelease modifier apply to all keys in combination definition. I.e. <'Control-KeyRelease-z'> will fire when all ([Control]-key and [z]-key) are released (after they has been simultaneously pressed)

Working modes

Callbacks can run asynchronously from main thread by two diferent aproach:

Threaded mode (default)

All binding callbacks run on a (only-one for all bindings) separate thread. Note that its your responsability to manage thread-safe interations with your main-thread (I.e. you cant call tkinter gui from inside callback). At least 4 threads will be running:

  1. main-thread
  2. and 3. keyboard-listener-thread and mouse-listener-thread (from pynput)
  3. callbacks-thread

Tkinter mode

All binding callbacks will be launched from tkinter main-loop (with tkinter event generation), so callbacks will be runnig in main-thread (you can safely call tkinter gui from inside callback). To enable this mode you have to provide a tkinter widget when init BindGlobal class:

root = tkinter.Tk() bg = BindGlobal(widget=root)

Please, note than more than one BindGlobal object can be created (every object with their own separate threads and bindings).

Methods:

bind / unbind

bg.bind(combination,callback,param) combination (or event): Combiantion string definition as standar tkinter bind command. If None, return all list of actual bindings callback: your callback funtion, that will be called everytime combination is detected. Must be defined to receive the event paratemter. if None, return actual bindings for this combination param: can be '+' to add new callbacks to same combination, or timeout seconds in '' event.

unbind works as expected tkinter unbind, removing bind callback

Examples of combinations:

'<Triple-Shift_R>': Triple clic over 'Right Shift' key

'<Double-Control_R-c>': fired when double-clic over 'c' key, while 'Right-Control' presed

Special Idle event

bg.bind('<Idle>',callback_when_idle,300)

callback_when_idle will be called when:

  • Every timeout=300 seconds with no keyboard or mouse action. Event will contain:
    • .event = '<Idle>'
    • .count = 1,2,....n (for every timeout)
  • Exit from idle mode (any keyboard or mouse event):
    • .event = '<after_idle>'
    • .count = 1

start, stop and pause

keyboard

bg.keyboard let access to internal pynput keyboard controller. In example: bg.keyboard.type("write this string")

mouse

bg.mouse let access to internal pynput mouse controller.

type

bg.keyboard.type("write this string")

Event

Bindglobal event (sended as parameter to every binded callback) follow the tkinter bind event structure:

  • event: The combination key-mouse that fire the callback, as created in bind method. '' or '<After_Idle>'
  • widget: The tkinter widget in tkinter mode or None in threaded mode
  • x, y: The current global mouse position, in pixels.
  • char: The character code (keyboard events only), as a string.
  • keysym: The key symbol (keyboard events only). Not implemented
  • keycode: The key code (keyboard events only).
  • num: The button number (mouse button events only).
  • type: The event type ('keyboard', 'mouse') that make fire the event.
  • time: datetime of last key/mouse that make fires the bind event
  • delta: mousewheel points (positve/negative
  • state: string showing modifiers keys like alt, control, shift, etc. in a 'alt_l+shift_r+' form (note this is not included in tkinter standard event)
  • count (%c): The count field from the event. In event: times the timeout has expired. In key events: the times key-pressed without key-released (repeated keys). In mouse clic-relese events, the total time in milliseconds of pressed button.

Depending on type of Pynput event however, not all attributes may be set.

Other examples:

Multiple callbacks

asociated to triple clic over 'f' key, (but launching on release):

bg.bind("<Triple-KeyRelease-f>",callback1)bg.bind("<Triple-KeyRelease-f>",callback2, '+')

Other keycodes

bg.bind("<65027>",lambda e: print("ALT-GR in LINUX"+str(e)))

Drag init (clic mouse, and movement without release)

bg.bind("<Motion-Button1>",lambda e: print("DRAG:"+str(e)))

Win+Alt key when release

bg.bind("<Command-Alt_L-KeyRelease>",lambda e: print("WIN+Alt:"+str(e)))

Press any key

bg.bind("<KeyPress>",callback5)

About

python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events)

Resources

Stars

10 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - segalion/bindglobal: python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events) · GitHub
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

bindglobal

bindglobal is a python-tkinter-bind alike, but run for system-wide global desktop: Windows, Linux (Xorg) and MacOS enviroments. It is based on pynput

You can easily define callbacks for mouse & keystrokes events, or any combination of them.

Follow instructions in python tkinter bind or tk bind documentation for definition of keyboard&mouse combinations.

In addition to bind, bindglobal add:

'<Idle>' to discover user inactivity based on no keyboard and mouse events

'<Long->' to get Long pressing of keys and buttons (not yet avaliable)

How to use

Install

with pip install bindglobal

Code

The minimum example, import, define callback functions, create a BindGlobal object, and bind combinations to callbaks.

from bindglobal import BindGlobal
def callback(event): print("running callback in another thread. Event=" + str(event)) def exit(event): print('exiting')
bg.stop()
bg = BindGlobal()
bg.bind("<Menu-1>",callback) bg.bind("<Triple-Escape>",exit) 

callback will be run in a separate thread every time you press [Menu key] + [Button1] mouse (left clic), simultaneously. exit will be called when triple-press [Esc] key.

Inportant notes:

  • Callbacks can not take long time to be executed, so other binding calls will be queued.

  • Keyrelease modifier apply to all keys in combination definition. I.e. <'Control-KeyRelease-z'> will fire when all ([Control]-key and [z]-key) are released (after they has been simultaneously pressed)

Working modes

Callbacks can run asynchronously from main thread by two diferent aproach:

Threaded mode (default)

All binding callbacks run on a (only-one for all bindings) separate thread. Note that its your responsability to manage thread-safe interations with your main-thread (I.e. you cant call tkinter gui from inside callback). At least 4 threads will be running:

  1. main-thread
  2. and 3. keyboard-listener-thread and mouse-listener-thread (from pynput)
  3. callbacks-thread

Tkinter mode

All binding callbacks will be launched from tkinter main-loop (with tkinter event generation), so callbacks will be runnig in main-thread (you can safely call tkinter gui from inside callback). To enable this mode you have to provide a tkinter widget when init BindGlobal class:

root = tkinter.Tk() bg = BindGlobal(widget=root)

Please, note than more than one BindGlobal object can be created (every object with their own separate threads and bindings).

Methods:

bind / unbind

bg.bind(combination,callback,param) combination (or event): Combiantion string definition as standar tkinter bind command. If None, return all list of actual bindings callback: your callback funtion, that will be called everytime combination is detected. Must be defined to receive the event paratemter. if None, return actual bindings for this combination param: can be '+' to add new callbacks to same combination, or timeout seconds in '' event.

unbind works as expected tkinter unbind, removing bind callback

Examples of combinations:

'<Triple-Shift_R>': Triple clic over 'Right Shift' key

'<Double-Control_R-c>': fired when double-clic over 'c' key, while 'Right-Control' presed

Special Idle event

bg.bind('<Idle>',callback_when_idle,300)

callback_when_idle will be called when:

  • Every timeout=300 seconds with no keyboard or mouse action. Event will contain:
    • .event = '<Idle>'
    • .count = 1,2,....n (for every timeout)
  • Exit from idle mode (any keyboard or mouse event):
    • .event = '<after_idle>'
    • .count = 1

start, stop and pause

keyboard

bg.keyboard let access to internal pynput keyboard controller. In example: bg.keyboard.type("write this string")

mouse

bg.mouse let access to internal pynput mouse controller.

type

bg.keyboard.type("write this string")

Event

Bindglobal event (sended as parameter to every binded callback) follow the tkinter bind event structure:

  • event: The combination key-mouse that fire the callback, as created in bind method. '' or '<After_Idle>'
  • widget: The tkinter widget in tkinter mode or None in threaded mode
  • x, y: The current global mouse position, in pixels.
  • char: The character code (keyboard events only), as a string.
  • keysym: The key symbol (keyboard events only). Not implemented
  • keycode: The key code (keyboard events only).
  • num: The button number (mouse button events only).
  • type: The event type ('keyboard', 'mouse') that make fire the event.
  • time: datetime of last key/mouse that make fires the bind event
  • delta: mousewheel points (positve/negative
  • state: string showing modifiers keys like alt, control, shift, etc. in a 'alt_l+shift_r+' form (note this is not included in tkinter standard event)
  • count (%c): The count field from the event. In event: times the timeout has expired. In key events: the times key-pressed without key-released (repeated keys). In mouse clic-relese events, the total time in milliseconds of pressed button.

Depending on type of Pynput event however, not all attributes may be set.

Other examples:

Multiple callbacks

asociated to triple clic over 'f' key, (but launching on release):

bg.bind("<Triple-KeyRelease-f>",callback1)bg.bind("<Triple-KeyRelease-f>",callback2, '+')

Other keycodes

bg.bind("<65027>",lambda e: print("ALT-GR in LINUX"+str(e)))

Drag init (clic mouse, and movement without release)

bg.bind("<Motion-Button1>",lambda e: print("DRAG:"+str(e)))

Win+Alt key when release

bg.bind("<Command-Alt_L-KeyRelease>",lambda e: print("WIN+Alt:"+str(e)))

Press any key

bg.bind("<KeyPress>",callback5)

About

python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events)

Resources

Stars

10 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - segalion/bindglobal: python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events) · GitHub
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

bindglobal

bindglobal is a python-tkinter-bind alike, but run for system-wide global desktop: Windows, Linux (Xorg) and MacOS enviroments. It is based on pynput

You can easily define callbacks for mouse & keystrokes events, or any combination of them.

Follow instructions in python tkinter bind or tk bind documentation for definition of keyboard&mouse combinations.

In addition to bind, bindglobal add:

'<Idle>' to discover user inactivity based on no keyboard and mouse events

'<Long->' to get Long pressing of keys and buttons (not yet avaliable)

How to use

Install

with pip install bindglobal

Code

The minimum example, import, define callback functions, create a BindGlobal object, and bind combinations to callbaks.

from bindglobal import BindGlobal
def callback(event): print("running callback in another thread. Event=" + str(event)) def exit(event): print('exiting')
bg.stop()
bg = BindGlobal()
bg.bind("<Menu-1>",callback) bg.bind("<Triple-Escape>",exit) 

callback will be run in a separate thread every time you press [Menu key] + [Button1] mouse (left clic), simultaneously. exit will be called when triple-press [Esc] key.

Inportant notes:

  • Callbacks can not take long time to be executed, so other binding calls will be queued.

  • Keyrelease modifier apply to all keys in combination definition. I.e. <'Control-KeyRelease-z'> will fire when all ([Control]-key and [z]-key) are released (after they has been simultaneously pressed)

Working modes

Callbacks can run asynchronously from main thread by two diferent aproach:

Threaded mode (default)

All binding callbacks run on a (only-one for all bindings) separate thread. Note that its your responsability to manage thread-safe interations with your main-thread (I.e. you cant call tkinter gui from inside callback). At least 4 threads will be running:

  1. main-thread
  2. and 3. keyboard-listener-thread and mouse-listener-thread (from pynput)
  3. callbacks-thread

Tkinter mode

All binding callbacks will be launched from tkinter main-loop (with tkinter event generation), so callbacks will be runnig in main-thread (you can safely call tkinter gui from inside callback). To enable this mode you have to provide a tkinter widget when init BindGlobal class:

root = tkinter.Tk() bg = BindGlobal(widget=root)

Please, note than more than one BindGlobal object can be created (every object with their own separate threads and bindings).

Methods:

bind / unbind

bg.bind(combination,callback,param) combination (or event): Combiantion string definition as standar tkinter bind command. If None, return all list of actual bindings callback: your callback funtion, that will be called everytime combination is detected. Must be defined to receive the event paratemter. if None, return actual bindings for this combination param: can be '+' to add new callbacks to same combination, or timeout seconds in '' event.

unbind works as expected tkinter unbind, removing bind callback

Examples of combinations:

'<Triple-Shift_R>': Triple clic over 'Right Shift' key

'<Double-Control_R-c>': fired when double-clic over 'c' key, while 'Right-Control' presed

Special Idle event

bg.bind('<Idle>',callback_when_idle,300)

callback_when_idle will be called when:

  • Every timeout=300 seconds with no keyboard or mouse action. Event will contain:
    • .event = '<Idle>'
    • .count = 1,2,....n (for every timeout)
  • Exit from idle mode (any keyboard or mouse event):
    • .event = '<after_idle>'
    • .count = 1

start, stop and pause

keyboard

bg.keyboard let access to internal pynput keyboard controller. In example: bg.keyboard.type("write this string")

mouse

bg.mouse let access to internal pynput mouse controller.

type

bg.keyboard.type("write this string")

Event

Bindglobal event (sended as parameter to every binded callback) follow the tkinter bind event structure:

  • event: The combination key-mouse that fire the callback, as created in bind method. '' or '<After_Idle>'
  • widget: The tkinter widget in tkinter mode or None in threaded mode
  • x, y: The current global mouse position, in pixels.
  • char: The character code (keyboard events only), as a string.
  • keysym: The key symbol (keyboard events only). Not implemented
  • keycode: The key code (keyboard events only).
  • num: The button number (mouse button events only).
  • type: The event type ('keyboard', 'mouse') that make fire the event.
  • time: datetime of last key/mouse that make fires the bind event
  • delta: mousewheel points (positve/negative
  • state: string showing modifiers keys like alt, control, shift, etc. in a 'alt_l+shift_r+' form (note this is not included in tkinter standard event)
  • count (%c): The count field from the event. In event: times the timeout has expired. In key events: the times key-pressed without key-released (repeated keys). In mouse clic-relese events, the total time in milliseconds of pressed button.

Depending on type of Pynput event however, not all attributes may be set.

Other examples:

Multiple callbacks

asociated to triple clic over 'f' key, (but launching on release):

bg.bind("<Triple-KeyRelease-f>",callback1)bg.bind("<Triple-KeyRelease-f>",callback2, '+')

Other keycodes

bg.bind("<65027>",lambda e: print("ALT-GR in LINUX"+str(e)))

Drag init (clic mouse, and movement without release)

bg.bind("<Motion-Button1>",lambda e: print("DRAG:"+str(e)))

Win+Alt key when release

bg.bind("<Command-Alt_L-KeyRelease>",lambda e: print("WIN+Alt:"+str(e)))

Press any key

bg.bind("<KeyPress>",callback5)

About

python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events)

Resources

Stars

10 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - segalion/bindglobal: python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events) · GitHub
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

bindglobal

bindglobal is a python-tkinter-bind alike, but run for system-wide global desktop: Windows, Linux (Xorg) and MacOS enviroments. It is based on pynput

You can easily define callbacks for mouse & keystrokes events, or any combination of them.

Follow instructions in python tkinter bind or tk bind documentation for definition of keyboard&mouse combinations.

In addition to bind, bindglobal add:

'<Idle>' to discover user inactivity based on no keyboard and mouse events

'<Long->' to get Long pressing of keys and buttons (not yet avaliable)

How to use

Install

with pip install bindglobal

Code

The minimum example, import, define callback functions, create a BindGlobal object, and bind combinations to callbaks.

from bindglobal import BindGlobal
def callback(event): print("running callback in another thread. Event=" + str(event)) def exit(event): print('exiting')
bg.stop()
bg = BindGlobal()
bg.bind("<Menu-1>",callback) bg.bind("<Triple-Escape>",exit) 

callback will be run in a separate thread every time you press [Menu key] + [Button1] mouse (left clic), simultaneously. exit will be called when triple-press [Esc] key.

Inportant notes:

  • Callbacks can not take long time to be executed, so other binding calls will be queued.

  • Keyrelease modifier apply to all keys in combination definition. I.e. <'Control-KeyRelease-z'> will fire when all ([Control]-key and [z]-key) are released (after they has been simultaneously pressed)

Working modes

Callbacks can run asynchronously from main thread by two diferent aproach:

Threaded mode (default)

All binding callbacks run on a (only-one for all bindings) separate thread. Note that its your responsability to manage thread-safe interations with your main-thread (I.e. you cant call tkinter gui from inside callback). At least 4 threads will be running:

  1. main-thread
  2. and 3. keyboard-listener-thread and mouse-listener-thread (from pynput)
  3. callbacks-thread

Tkinter mode

All binding callbacks will be launched from tkinter main-loop (with tkinter event generation), so callbacks will be runnig in main-thread (you can safely call tkinter gui from inside callback). To enable this mode you have to provide a tkinter widget when init BindGlobal class:

root = tkinter.Tk() bg = BindGlobal(widget=root)

Please, note than more than one BindGlobal object can be created (every object with their own separate threads and bindings).

Methods:

bind / unbind

bg.bind(combination,callback,param) combination (or event): Combiantion string definition as standar tkinter bind command. If None, return all list of actual bindings callback: your callback funtion, that will be called everytime combination is detected. Must be defined to receive the event paratemter. if None, return actual bindings for this combination param: can be '+' to add new callbacks to same combination, or timeout seconds in '' event.

unbind works as expected tkinter unbind, removing bind callback

Examples of combinations:

'<Triple-Shift_R>': Triple clic over 'Right Shift' key

'<Double-Control_R-c>': fired when double-clic over 'c' key, while 'Right-Control' presed

Special Idle event

bg.bind('<Idle>',callback_when_idle,300)

callback_when_idle will be called when:

  • Every timeout=300 seconds with no keyboard or mouse action. Event will contain:
    • .event = '<Idle>'
    • .count = 1,2,....n (for every timeout)
  • Exit from idle mode (any keyboard or mouse event):
    • .event = '<after_idle>'
    • .count = 1

start, stop and pause

keyboard

bg.keyboard let access to internal pynput keyboard controller. In example: bg.keyboard.type("write this string")

mouse

bg.mouse let access to internal pynput mouse controller.

type

bg.keyboard.type("write this string")

Event

Bindglobal event (sended as parameter to every binded callback) follow the tkinter bind event structure:

  • event: The combination key-mouse that fire the callback, as created in bind method. '' or '<After_Idle>'
  • widget: The tkinter widget in tkinter mode or None in threaded mode
  • x, y: The current global mouse position, in pixels.
  • char: The character code (keyboard events only), as a string.
  • keysym: The key symbol (keyboard events only). Not implemented
  • keycode: The key code (keyboard events only).
  • num: The button number (mouse button events only).
  • type: The event type ('keyboard', 'mouse') that make fire the event.
  • time: datetime of last key/mouse that make fires the bind event
  • delta: mousewheel points (positve/negative
  • state: string showing modifiers keys like alt, control, shift, etc. in a 'alt_l+shift_r+' form (note this is not included in tkinter standard event)
  • count (%c): The count field from the event. In event: times the timeout has expired. In key events: the times key-pressed without key-released (repeated keys). In mouse clic-relese events, the total time in milliseconds of pressed button.

Depending on type of Pynput event however, not all attributes may be set.

Other examples:

Multiple callbacks

asociated to triple clic over 'f' key, (but launching on release):

bg.bind("<Triple-KeyRelease-f>",callback1)bg.bind("<Triple-KeyRelease-f>",callback2, '+')

Other keycodes

bg.bind("<65027>",lambda e: print("ALT-GR in LINUX"+str(e)))

Drag init (clic mouse, and movement without release)

bg.bind("<Motion-Button1>",lambda e: print("DRAG:"+str(e)))

Win+Alt key when release

bg.bind("<Command-Alt_L-KeyRelease>",lambda e: print("WIN+Alt:"+str(e)))

Press any key

bg.bind("<KeyPress>",callback5)

About

python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events)

Resources

Stars

10 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - segalion/bindglobal: python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events) · GitHub
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

bindglobal

bindglobal is a python-tkinter-bind alike, but run for system-wide global desktop: Windows, Linux (Xorg) and MacOS enviroments. It is based on pynput

You can easily define callbacks for mouse & keystrokes events, or any combination of them.

Follow instructions in python tkinter bind or tk bind documentation for definition of keyboard&mouse combinations.

In addition to bind, bindglobal add:

'<Idle>' to discover user inactivity based on no keyboard and mouse events

'<Long->' to get Long pressing of keys and buttons (not yet avaliable)

How to use

Install

with pip install bindglobal

Code

The minimum example, import, define callback functions, create a BindGlobal object, and bind combinations to callbaks.

from bindglobal import BindGlobal
def callback(event): print("running callback in another thread. Event=" + str(event)) def exit(event): print('exiting')
bg.stop()
bg = BindGlobal()
bg.bind("<Menu-1>",callback) bg.bind("<Triple-Escape>",exit) 

callback will be run in a separate thread every time you press [Menu key] + [Button1] mouse (left clic), simultaneously. exit will be called when triple-press [Esc] key.

Inportant notes:

  • Callbacks can not take long time to be executed, so other binding calls will be queued.

  • Keyrelease modifier apply to all keys in combination definition. I.e. <'Control-KeyRelease-z'> will fire when all ([Control]-key and [z]-key) are released (after they has been simultaneously pressed)

Working modes

Callbacks can run asynchronously from main thread by two diferent aproach:

Threaded mode (default)

All binding callbacks run on a (only-one for all bindings) separate thread. Note that its your responsability to manage thread-safe interations with your main-thread (I.e. you cant call tkinter gui from inside callback). At least 4 threads will be running:

  1. main-thread
  2. and 3. keyboard-listener-thread and mouse-listener-thread (from pynput)
  3. callbacks-thread

Tkinter mode

All binding callbacks will be launched from tkinter main-loop (with tkinter event generation), so callbacks will be runnig in main-thread (you can safely call tkinter gui from inside callback). To enable this mode you have to provide a tkinter widget when init BindGlobal class:

root = tkinter.Tk() bg = BindGlobal(widget=root)

Please, note than more than one BindGlobal object can be created (every object with their own separate threads and bindings).

Methods:

bind / unbind

bg.bind(combination,callback,param) combination (or event): Combiantion string definition as standar tkinter bind command. If None, return all list of actual bindings callback: your callback funtion, that will be called everytime combination is detected. Must be defined to receive the event paratemter. if None, return actual bindings for this combination param: can be '+' to add new callbacks to same combination, or timeout seconds in '' event.

unbind works as expected tkinter unbind, removing bind callback

Examples of combinations:

'<Triple-Shift_R>': Triple clic over 'Right Shift' key

'<Double-Control_R-c>': fired when double-clic over 'c' key, while 'Right-Control' presed

Special Idle event

bg.bind('<Idle>',callback_when_idle,300)

callback_when_idle will be called when:

  • Every timeout=300 seconds with no keyboard or mouse action. Event will contain:
    • .event = '<Idle>'
    • .count = 1,2,....n (for every timeout)
  • Exit from idle mode (any keyboard or mouse event):
    • .event = '<after_idle>'
    • .count = 1

start, stop and pause

keyboard

bg.keyboard let access to internal pynput keyboard controller. In example: bg.keyboard.type("write this string")

mouse

bg.mouse let access to internal pynput mouse controller.

type

bg.keyboard.type("write this string")

Event

Bindglobal event (sended as parameter to every binded callback) follow the tkinter bind event structure:

  • event: The combination key-mouse that fire the callback, as created in bind method. '' or '<After_Idle>'
  • widget: The tkinter widget in tkinter mode or None in threaded mode
  • x, y: The current global mouse position, in pixels.
  • char: The character code (keyboard events only), as a string.
  • keysym: The key symbol (keyboard events only). Not implemented
  • keycode: The key code (keyboard events only).
  • num: The button number (mouse button events only).
  • type: The event type ('keyboard', 'mouse') that make fire the event.
  • time: datetime of last key/mouse that make fires the bind event
  • delta: mousewheel points (positve/negative
  • state: string showing modifiers keys like alt, control, shift, etc. in a 'alt_l+shift_r+' form (note this is not included in tkinter standard event)
  • count (%c): The count field from the event. In event: times the timeout has expired. In key events: the times key-pressed without key-released (repeated keys). In mouse clic-relese events, the total time in milliseconds of pressed button.

Depending on type of Pynput event however, not all attributes may be set.

Other examples:

Multiple callbacks

asociated to triple clic over 'f' key, (but launching on release):

bg.bind("<Triple-KeyRelease-f>",callback1)bg.bind("<Triple-KeyRelease-f>",callback2, '+')

Other keycodes

bg.bind("<65027>",lambda e: print("ALT-GR in LINUX"+str(e)))

Drag init (clic mouse, and movement without release)

bg.bind("<Motion-Button1>",lambda e: print("DRAG:"+str(e)))

Win+Alt key when release

bg.bind("<Command-Alt_L-KeyRelease>",lambda e: print("WIN+Alt:"+str(e)))

Press any key

bg.bind("<KeyPress>",callback5)

About

python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events)

Resources

Stars

10 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - segalion/bindglobal: python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events) · GitHub
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

bindglobal

bindglobal is a python-tkinter-bind alike, but run for system-wide global desktop: Windows, Linux (Xorg) and MacOS enviroments. It is based on pynput

You can easily define callbacks for mouse & keystrokes events, or any combination of them.

Follow instructions in python tkinter bind or tk bind documentation for definition of keyboard&mouse combinations.

In addition to bind, bindglobal add:

'<Idle>' to discover user inactivity based on no keyboard and mouse events

'<Long->' to get Long pressing of keys and buttons (not yet avaliable)

How to use

Install

with pip install bindglobal

Code

The minimum example, import, define callback functions, create a BindGlobal object, and bind combinations to callbaks.

from bindglobal import BindGlobal
def callback(event): print("running callback in another thread. Event=" + str(event)) def exit(event): print('exiting')
bg.stop()
bg = BindGlobal()
bg.bind("<Menu-1>",callback) bg.bind("<Triple-Escape>",exit) 

callback will be run in a separate thread every time you press [Menu key] + [Button1] mouse (left clic), simultaneously. exit will be called when triple-press [Esc] key.

Inportant notes:

  • Callbacks can not take long time to be executed, so other binding calls will be queued.

  • Keyrelease modifier apply to all keys in combination definition. I.e. <'Control-KeyRelease-z'> will fire when all ([Control]-key and [z]-key) are released (after they has been simultaneously pressed)

Working modes

Callbacks can run asynchronously from main thread by two diferent aproach:

Threaded mode (default)

All binding callbacks run on a (only-one for all bindings) separate thread. Note that its your responsability to manage thread-safe interations with your main-thread (I.e. you cant call tkinter gui from inside callback). At least 4 threads will be running:

  1. main-thread
  2. and 3. keyboard-listener-thread and mouse-listener-thread (from pynput)
  3. callbacks-thread

Tkinter mode

All binding callbacks will be launched from tkinter main-loop (with tkinter event generation), so callbacks will be runnig in main-thread (you can safely call tkinter gui from inside callback). To enable this mode you have to provide a tkinter widget when init BindGlobal class:

root = tkinter.Tk() bg = BindGlobal(widget=root)

Please, note than more than one BindGlobal object can be created (every object with their own separate threads and bindings).

Methods:

bind / unbind

bg.bind(combination,callback,param) combination (or event): Combiantion string definition as standar tkinter bind command. If None, return all list of actual bindings callback: your callback funtion, that will be called everytime combination is detected. Must be defined to receive the event paratemter. if None, return actual bindings for this combination param: can be '+' to add new callbacks to same combination, or timeout seconds in '' event.

unbind works as expected tkinter unbind, removing bind callback

Examples of combinations:

'<Triple-Shift_R>': Triple clic over 'Right Shift' key

'<Double-Control_R-c>': fired when double-clic over 'c' key, while 'Right-Control' presed

Special Idle event

bg.bind('<Idle>',callback_when_idle,300)

callback_when_idle will be called when:

  • Every timeout=300 seconds with no keyboard or mouse action. Event will contain:
    • .event = '<Idle>'
    • .count = 1,2,....n (for every timeout)
  • Exit from idle mode (any keyboard or mouse event):
    • .event = '<after_idle>'
    • .count = 1

start, stop and pause

keyboard

bg.keyboard let access to internal pynput keyboard controller. In example: bg.keyboard.type("write this string")

mouse

bg.mouse let access to internal pynput mouse controller.

type

bg.keyboard.type("write this string")

Event

Bindglobal event (sended as parameter to every binded callback) follow the tkinter bind event structure:

  • event: The combination key-mouse that fire the callback, as created in bind method. '' or '<After_Idle>'
  • widget: The tkinter widget in tkinter mode or None in threaded mode
  • x, y: The current global mouse position, in pixels.
  • char: The character code (keyboard events only), as a string.
  • keysym: The key symbol (keyboard events only). Not implemented
  • keycode: The key code (keyboard events only).
  • num: The button number (mouse button events only).
  • type: The event type ('keyboard', 'mouse') that make fire the event.
  • time: datetime of last key/mouse that make fires the bind event
  • delta: mousewheel points (positve/negative
  • state: string showing modifiers keys like alt, control, shift, etc. in a 'alt_l+shift_r+' form (note this is not included in tkinter standard event)
  • count (%c): The count field from the event. In event: times the timeout has expired. In key events: the times key-pressed without key-released (repeated keys). In mouse clic-relese events, the total time in milliseconds of pressed button.

Depending on type of Pynput event however, not all attributes may be set.

Other examples:

Multiple callbacks

asociated to triple clic over 'f' key, (but launching on release):

bg.bind("<Triple-KeyRelease-f>",callback1)bg.bind("<Triple-KeyRelease-f>",callback2, '+')

Other keycodes

bg.bind("<65027>",lambda e: print("ALT-GR in LINUX"+str(e)))

Drag init (clic mouse, and movement without release)

bg.bind("<Motion-Button1>",lambda e: print("DRAG:"+str(e)))

Win+Alt key when release

bg.bind("<Command-Alt_L-KeyRelease>",lambda e: print("WIN+Alt:"+str(e)))

Press any key

bg.bind("<KeyPress>",callback5)

About

python-tkinter-bind alike, for global desktop enviroment (callbacks for mouse&keystrokes events)

Resources

Stars

10 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors