Xpra-org / xpra

Persistent remote applications for X11; screen sharing for X11, MacOS and MSWindows.
https://xpra.org/
GNU General Public License v2.0
1.94k stars 168 forks source link

MS Windows taskbar integration #508

Closed totaam closed 2 years ago

totaam commented 10 years ago

Windows 7 onwards support customization of the taskbar entry for our application, we could do something with it:

Pointers:

See also #472

totaam commented 9 years ago

Best example code found so far:

totaam commented 9 years ago

2015-09-30 07:52:34: antoine uploaded file TaskbarLib.idl (2.7 KiB)

copy of the idl file

totaam commented 9 years ago

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.

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}')
totaam commented 9 years ago

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:

totaam commented 2 years ago

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

totaam commented 2 years ago

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.