python-wnck set focus to window - python

I'm trying to set focus to a window using python-wnck.
The only docs I could find related to this library are from https://developer.gnome.org/libwnck/stable/WnckWindow.html
Using some code I found on another question here at SO, I was able to search for windows using the window title, but I'm not sure how to get a window to focus. From the above docs I found the function:
wnck_window_activate(WnckWindow *window, guint32 timestamp);
So in python I tried using this function like "window.activate(0)", but this appears to fail, the icon on my taskbar flashed but it doesn't get focus.In the terminal I get the message:
(windowTest.py:17485): Wnck-WARNING: Received a timestamp of 0; window activation may not function properly
So I think I may actually need to put in a valid timestamp but not sure how to get this.
This is the code Im using sofar:
import pygtk
pygtk.require('2.0')
import gtk
import wnck
import re
import sys
screen = wnck.screen_get_default()
while gtk.events_pending():
gtk.main_iteration()
titlePattern = re.compile('.*Geany.*')
windows = screen.get_windows()
for w in windows:
if titlePattern.match(w.get_name()):
print w.get_name()
w.activate(0)

The solution was actually pretty simpleI just needed to "import time" then pass "int(time.time())" into the activate function
Working code:
import pygtk
pygtk.require('2.0')
import gtk
import wnck
import re
import sys
import time
screen = wnck.screen_get_default()
while gtk.events_pending():
gtk.main_iteration()
titlePattern = re.compile('.*Geany.*')
windows = screen.get_windows()
for w in windows:
if titlePattern.match(w.get_name()):
print w.get_name()
w.activate(int(time.time()))

To get away from the Wnck-WARNING, you need to send a valid timestamp with the w.activate() function. The way that I found to do this is to use:
now = gtk.gdk.x11_get_server_time(gtk.gdk.get_default_root_window())
w.activate(now)
There really should be an easier way to do this, or wnck should allow a timestamp of 0 to mean now like most of the gtk libraries use.

Related

Python Win32API SendMessage win32con WM_SETTEXT only works once

Simplified and working code below, but only works once then not again until the window is restarted. Is there some sort of finish set text missing or some other limitation? Can't find any results on google, Thanks
import win32api
import win32gui
import win32con
handle = windowName #Script is working with actual window name
mainWindowHWND = win32gui.FindWindow(None, handle)
win32api.SendMessage(mainWindowHWND, win32con.WM_SETTEXT, 0, "test")
You need to find the exact control handle in order to send the text. Now, you are changing the window title of that program. So Assume that you are setting a notepad window's title to 'test'. Then it become a window with title 'test'. So you can't get the window handle again with the old text.
You need to enumerate the all the child windows of that specific window and check the type of control you are interested in. Then set the text of that control You can use EnumChildWindows api function for that.
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumchildwindows

Python, tkinter how to make the window click-through Linux

I have seen the post about how to do it on Windows, but i need a Linux version. Is there any way? (Yes, i Googled before i came here)
What i basically want to do is to open a maximized transparent click through window, to mainly use it as a "dark reader"
here my tiny code :)
from tkinter import *
win = Tk()
win.geometry("%dx%d+0+0" % (win.winfo_screenwidth(), win.winfo_screenheight()))
win.wait_visibility(win)
win.configure(bg="black")
win.wm_attributes("-alpha", 0.5)
win.mainloop()
I forgot to answer my question, after i got the solution. Thanks to Andrew Hernandez, i checked out PyQT5 and with that i could make what i needed. Here the code:
from PyQt5 import QtCore, QtWidgets, QtGui
import sys
DR = QtWidgets.QApplication(sys.argv)
win = QtWidgets.QWidget()
screen = DR.primaryScreen()
size = screen.size()
w = size.width()
h = size.height()
win.resize(w, h)
win.setWindowTitle("Dark Reader")
win.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents, True)
win.setStyleSheet("background-color: black;")
win.setWindowOpacity(0.5)
win.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.FramelessWindowHint)
win.showMaximized()
sys.exit(DR.exec_())
Simplified Explication
#Z3r0ut, Your probably using python 2.x because that is what most Linux distributions use. If you want to run the code, you can simple start with this argument python %FILENAME%.py.
!/usr/bin/python
-*- encoding: utf8 -*-
try:
import Tkinter as tk
from Tkinter import *
except ImportError:
win = Tk()
win.geometry("%dx%d+0+0" % (win.winfo_screenwidth(), win.winfo_screenheight()))
win.wait_visibility(win)
win.configure(bg="black")
win.wm_attributes("-alpha", 0.5)
win.mainloop()
Detailed Explication
These effects depend on your operating system, therefore you can't make Linux re-create these effects like windows 10/11. For example, shader.dll is used for shaders, dynamic.dll is used for screen smoothing, fix.dll is used for styling windows. Every one, can be found on regedit.
It can be made, but you need third-party API's or links for your file. If you're trying to make it, I would recommend you using c/c++ for it!

How to avoid lock screen under Win10 via Python code? [duplicate]

I tried to use this script to prevent windows screen lock. The script works for moving the mouse, but it doesn't prevent windows 10 from locking.
import pyautogui
import time
import win32gui, win32con
import os
Minimize = win32gui.GetForegroundWindow()
win32gui.ShowWindow(Minimize, win32con.SW_MINIMIZE)
x = 1
while x == 1:
pyautogui.moveRel(1)
pyautogui.moveRel(-1)
time.sleep (300)
Yes it can. But sadly not by moving mouse which I don't know why and would like to know. So, my suggestion is to use pyautogui KEYBOARD EVENTS if possible. I have solved my problems by using VOLUME-UP & VOLUME-DOWN keys. Example code is provided below:
import pyautogui
import time
while True:
pyautogui.press('volumedown')
time.sleep(1)
pyautogui.press('volumeup')
time.sleep(5)
You can use any other keys if you want.
import ctypes
# prevent
ctypes.windll.kernel32.SetThreadExecutionState(0x80000002)
# set back to normal
ctypes.windll.kernel32.SetThreadExecutionState(0x80000000)
https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate
Tested on python 3.9.1, win 10 64bit

Accessing selection clipboard from ipython

I want to access the text in the clipboard from within ipython.
I got this far (not even sure if this is the best way, just found by poking around in ipython magics sources):
import IPython
from IPython.core.hooks import clipboard_get
ip = IPython.get_ipython()
my_string = clipboard_get(ip)
And it kinda works for stuff I've copied manually, but I want to get the "other" clipboard - the one you get when you use the middle mouse click. The selection buffer or whatever it's called.
Any ideas?
You can get X Window's "middle mouse button" selection (called the PRIMARY selection) through Tkinter:
import Tkinter # Replace "Tkinter" with "tkinter" for Python 3.x.
tk = Tkinter.Tk()
tk.withdraw()
print(tk.selection_get())
Another solution is to run xclip and get its output. (If you don't have xclip installed it can be found in most Linux distributions' package repositories.)
import subprocess
print(subprocess.check_output(['xclip', '-o', '-selection', 'PRIMARY']))

Python Message Box Without huge library dependency

Is there a messagebox class where I can just display a simple message box without a huge GUI library or any library upon program success or failure. (My script only does 1 thing).
Also, I only need it to run on Windows.
You can use the ctypes library, which comes installed with Python:
import ctypes
MessageBox = ctypes.windll.user32.MessageBoxW
MessageBox(None, 'Hello', 'Window title', 0)
Above code is for Python 3.x. For Python 2.x, use MessageBoxA instead of MessageBoxW as Python 2 uses non-unicode strings by default.
There are also a couple prototyped in the default libraries without using ctypes.
Simple message box:
import win32ui
win32ui.MessageBox("Message", "Title")
Other Options
if win32ui.MessageBox("Message", "Title", win32con.MB_YESNOCANCEL) == win32con.IDYES:
win32ui.MessageBox("You pressed 'Yes'")
There's also a roughly equivalent one in win32gui and another in win32api. Docs for all appear to be in C:\Python{nn}\Lib\site-packages\PyWin32.chm
The PyMsgBox module uses Python's tkinter, so it doesn't depend on any other third-party modules. You can install it with pip install pymsgbox.
The function names are similar to JavaScript's alert(), confirm(), and prompt() functions:
>>> import pymsgbox
>>> pymsgbox.alert('This is an alert!')
>>> user_response = pymsgbox.prompt('What is your favorite color?')
A quick and dirty way is to call OS and use "zenity" command (subprocess module should be included by default in any python distribution, zenity is also present in all major linux). Try this short example script, it works in my Ubuntu 14.04.
import subprocess as SP
# call an OS subprocess $ zenity --entry --text "some text"
# (this will ask OS to open a window with the dialog)
res=SP.Popen(['zenity','--entry','--text',
'please write some text'], stdout=SP.PIPE)
# get the user input string back
usertext=str(res.communicate()[0][:-1])
# adjust user input string
text=usertext[2:-1]
print("I got this text from the user: %s"%text)
See the zenity --help for more complex dialogs
You can also use the messagebox class from tkinter:
from tkinter import messagebox
unless tkinter is that huge GUI you want to avoid.
Usage is simple, ie:
messagebox.FunctionName(title, message [, options])
with FuntionName in (showinfo, showwarning, showerror, askquestion, askokcancel, askyesno, askretrycancel).
This one with tkinter.
from tkinter import * #required.
from tkinter import messagebox #for messagebox.
App = Tk() #required.
App.withdraw() #for hide window.
print("Message Box in Console")
messagebox.showinfo("Notification", "Hello World!") #msgbox
App.mainloop() #required.

Categories