Closed totaam closed 2 years ago
Best example code found so far:
TaskbarLib.idl
(2.7 KiB)copy of the idl file
The examples in comment 4 work but this is not the interface we need. We could still use them to enhance the tray/menu classes with progress bar support, etc.
midl TaskbarLib.idl /tlb TaskbarLib.tlb
import gtk
window = gtk.Window()
window.show()
import comtypes.client as cc cc.GetModule("TaskbarLib.tlb") import comtypes.gen.TaskbarLib as tbl taskbar = cc.CreateObject("{56FDF344-FD6D-11d0-958A-006097C9A090}", interface=tbl.ITaskbarList3) taskbar.HrInit() taskbar.SetProgressValue(window.get_window().handle,40,100)
---
For the menus, what we want is [Tasks](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks) and more specifically: [AddUserTasks](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378395(v=vs.85).aspx).
There is some support for it in pywin32 already:
```python
> from win32com.shell import shell
> shell.CLSID_DestinationList
IID('{77F10CF0-3DB5-4966-B520-B7C54FD35ED6}')
By the looks of things, "tasks" is not it: present even when the application is not running. Maybe Jump Lists? But even that is not a good fit...
The only workable solutions that I can think of are:
Both of which would have all sorts of interesting interactions with window hints, size constraints, events, position...
Unrelated:
import pythoncom
pythoncom.CoCreateInstance(shell.CLSID_ShellItem, None, pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellItem)
We now use the taskbar progress to show:
One problem is that I had to un-silence comtypes because turning off debugging triggers a strange tlb
loading bug!
Should we also use the icon overlay for clipboard and / or notifications? https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setoverlayicon
This will do.
I have also tried adding support for SetOverlayIcon
and triggering it when the window beeps using:
handle = get_window_handle(window)
icon_path = get_icon_filename("blue-dot.png")
from PIL import Image #@UnresolvedImport
img = Image.open(icon_path)
hicon = HICON(image_to_ICONINFO(img))
taskbar.SetOverlayIcon(handle, hicon, "Attention requested")
But as usual, comtypes
is failing with an opaque error:
hicon(E:/xpra/dist/share/xpra/icons/blue-dot.png)=c_void_p(113443719)
taskbar.SetOverlayIcon=<bound method SetOverlayIcon of <POINTER(ITaskbarList3) ptr=0x1e39dd1f320 at 1e3bfbc71c0>> (<class 'method'>)
Traceback (most recent call last):
File "E:/xpra/xpra/client/client_base.py", line 1129, in call_handler
handler(packet)
File "E:/xpra/xpra/client/mixins/window_manager.py", line 1282, in _process_bell
self.window_bell(window, device, percent, pitch, duration, bell_class, bell_id, bell_name)
File "E:/xpra/xpra/client/gtk_base/gtk_client_base.py", line 1098, in window_bell
set_attention_requested(window, True)
File "E:/xpra/dist/lib/xpra/platform/win32/gui.py", line 1008, in set_attention_requested
taskbar.SetOverlayIcon(handle, hicon, label)
ctypes.ArgumentError: argument 2: <class 'AttributeError'>: 'c_void_p' object has no attribute 'QueryInterface'
We're not using c_void_p
here but an LPCWSTR
, or 0
or a plain string, whatever. No dice.
Windows 7 onwards support customization of the taskbar entry for our application, we could do something with it:
Pointers:
See also #472