5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-10 22:19:46 +08:00

Add systray.SetTooltip

This commit is contained in:
Lea Anthony 2025-02-08 14:01:22 +11:00
parent 2db902ef82
commit d427e9d750
No known key found for this signature in database
GPG Key ID: 33DAF7BB90A58405
8 changed files with 90 additions and 10 deletions

View File

@ -45,6 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- More documentation by [@leaanthony](https://github.com/leaanthony)
- Support cancellation of events in standard event listeners by [@leaanthony](https://github.com/leaanthony)
- Systray `Hide`, `Show` and `Destroy` support by [@leaanthony](https://github.com/leaanthony)
- Systray `SetTooltip` support by [@leaanthony](https://github.com/leaanthony). Original idea by [@lujihong](https://github.com/wailsapp/wails/issues/3487#issuecomment-2633242304)
### Fixed

View File

@ -56,6 +56,14 @@ systray.SetTemplateIcon(iconBytes)
For more details on creating template icons, read this [great article](https://bjango.com/articles/designingmenubarextras/).
## Setting the Tooltip <Badge text="Windows" variant="note" />
You can set a tooltip for your system tray icon that appears when hovering over the icon:
```go
systray.SetTooltip("My Application Tooltip")
```
## Setting the Label <Badge text="macOS" variant="success" />
You can set a text label for your system tray icon:
@ -66,6 +74,10 @@ systray.SetLabel("My App")
The label will appear next to the icon in the system tray. On some platforms, this text may be truncated if it's too long.
:::note
On Windows, setting the label is the equivalent of setting the tooltip.
:::
## Adding a Menu
You can add a menu to your system tray icon:
@ -172,6 +184,7 @@ Explore these examples for more advanced usage:
| `NewSystemTray()` | Creates a new system tray instance |
| `Run()` | Starts the system tray |
| `SetLabel(label string)` | Sets the text label |
| `SetTooltip(tooltip string)` | Sets the tooltip text (Windows) |
| `SetIcon(icon []byte)` | Sets the icon image |
| `SetDarkModeIcon(icon []byte)` | Sets the dark mode variant of the icon |
| `SetTemplateIcon(icon []byte)` | Marks the icon as a template image (macOS) |
@ -208,4 +221,3 @@ Explore these examples for more advanced usage:
|----------|-----------------------------|
| `Show()` | Makes the tray icon visible |
| `Hide()` | Hides the tray icon |

View File

@ -56,6 +56,7 @@ func main() {
app.Quit()
})
systemTray.SetMenu(menu)
systemTray.SetTooltip("Systray Demo")
if runtime.GOOS == "darwin" {
systemTray.SetTemplateIcon(icons.SystrayMacTemplate)

View File

@ -25,6 +25,7 @@ const (
type systemTrayImpl interface {
setLabel(label string)
setTooltip(tooltip string)
run()
setIcon(icon []byte)
setMenu(menu *Menu)
@ -43,6 +44,7 @@ type systemTrayImpl interface {
type SystemTray struct {
id uint
label string
tooltip string
icon []byte
darkModeIcon []byte
iconPosition IconPosition
@ -67,6 +69,7 @@ func newSystemTray(id uint) *SystemTray {
result := &SystemTray{
id: id,
label: "",
tooltip: "",
iconPosition: NSImageLeading,
attachedWindow: WindowAttachConfig{
Window: nil,
@ -183,6 +186,16 @@ func (s *SystemTray) SetTemplateIcon(icon []byte) *SystemTray {
return s
}
func (s *SystemTray) SetTooltip(tooltip string) {
if s.impl == nil {
s.tooltip = tooltip
return
}
InvokeSync(func() {
s.impl.setTooltip(tooltip)
})
}
func (s *SystemTray) Destroy() {
globalApplication.destroySystemTray(s)
}

View File

@ -189,6 +189,10 @@ func (s *macosSystemTray) setTemplateIcon(icon []byte) {
})
}
func (s *macosSystemTray) setTooltip(tooltip string) {
// Tooltips not supported on macOS
}
func newSystemTrayImpl(s *SystemTray) systemTrayImpl {
result := &macosSystemTray{
parent: s,

View File

@ -6,16 +6,16 @@ Portions of this code are derived from the project:
*/
package application
import "C"
import (
"fmt"
"os"
"github.com/godbus/dbus/v5"
"github.com/godbus/dbus/v5/introspect"
"github.com/godbus/dbus/v5/prop"
"github.com/wailsapp/wails/v3/internal/dbus/menu"
"github.com/wailsapp/wails/v3/internal/dbus/notifier"
"github.com/wailsapp/wails/v3/pkg/icons"
"os"
)
const (
@ -31,7 +31,7 @@ type linuxSystemTray struct {
icon []byte
menu *Menu
iconPosition int
iconPosition IconPosition
isTemplateIcon bool
quitChan chan struct{}
@ -41,6 +41,7 @@ type linuxSystemTray struct {
menuVersion uint32 // need to bump this anytime we change anything
itemMap map[int32]*systrayMenuItem
tooltip string
}
func (s *linuxSystemTray) getScreen() (*Screen, error) {
@ -103,9 +104,9 @@ func (s *systrayMenuItem) setHidden(hidden bool) {
s.sysTray.update(s)
}
func (i systrayMenuItem) dbus() *dbusMenu {
func (s *systrayMenuItem) dbus() *dbusMenu {
item := &dbusMenu{
V0: int32(i.menuItem.id),
V0: int32(s.menuItem.id),
V1: map[string]dbus.Variant{},
V2: []dbus.Variant{},
}
@ -364,9 +365,21 @@ func (s *linuxSystemTray) run() {
}
}
}()
if s.parent.label != "" {
s.setLabel(s.parent.label)
}
if s.parent.tooltip != "" {
s.setTooltip(s.parent.tooltip)
}
s.setMenu(s.menu)
}
func (s *linuxSystemTray) setTooltip(_ string) {
// TBD
}
func (s *linuxSystemTray) setIcon(icon []byte) {
s.icon = icon

View File

@ -223,6 +223,10 @@ func (s *windowsSystemTray) run() {
s.updateMenu(s.parent.menu)
}
if s.parent.tooltip != "" {
s.setTooltip(s.parent.tooltip)
}
// Set Default Callbacks
if s.parent.clickHandler == nil {
s.parent.clickHandler = func() {
@ -367,12 +371,36 @@ func (s *windowsSystemTray) updateMenu(menu *Menu) {
s.menu.Update()
}
// ---- Unsupported ----
// Based on the idea from https://github.com/wailsapp/wails/issues/3487#issuecomment-2633242304
func (s *windowsSystemTray) setTooltip(tooltip string) {
// Ensure the tooltip length is within the limit (64 characters for szTip)
if len(tooltip) > 64 {
tooltip = tooltip[:64]
}
func (s *windowsSystemTray) setLabel(_ string) {
// Unsupported - do nothing
// Create a new NOTIFYICONDATA structure
nid := s.newNotifyIconData()
nid.UFlags = w32.NIF_TIP
tooltipUTF16, err := w32.StringToUTF16(tooltip)
if err != nil {
return
}
copy(nid.SzTip[:], tooltipUTF16)
// Modify the tray icon with the new tooltip
if !w32.ShellNotifyIcon(w32.NIM_MODIFY, &nid) {
return
}
nid.UVersion = 3 // Version 4 does not suport
if !w32.ShellNotifyIcon(w32.NIM_SETVERSION, &nid) {
return
}
}
// ---- Unsupported ----
func (s *windowsSystemTray) setLabel(label string) {}
func (s *windowsSystemTray) setTemplateIcon(_ []byte) {
// Unsupported - do nothing
}

View File

@ -191,6 +191,11 @@ func MustStringToUTF16(input string) []uint16 {
return lo.Must(syscall.UTF16FromString(input))
}
func StringToUTF16(input string) ([]uint16, error) {
input = stripNulls(input)
return syscall.UTF16FromString(input)
}
func CenterWindow(hwnd HWND) {
windowInfo := getWindowInfo(hwnd)
frameless := windowInfo.IsPopup()
@ -329,7 +334,10 @@ func FindWindowW(className, windowName *uint16) HWND {
func SendMessageToWindow(hwnd HWND, msg string) {
// Convert data to UTF16 string
dataUTF16 := MustStringToUTF16(msg)
dataUTF16, err := StringToUTF16(msg)
if err != nil {
return
}
// Prepare COPYDATASTRUCT
cds := COPYDATASTRUCT{