Skip to content

Commit a8de6e6

Browse files
committed
Merge branch 'v3-alpha' into v3-alpha-bugfix/assetserver
2 parents 4c08fec + d427e9d commit a8de6e6

File tree

8 files changed

+90
-10
lines changed

8 files changed

+90
-10
lines changed

docs/src/content/docs/changelog.mdx

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

4950
### Fixed
5051

docs/src/content/docs/learn/systray.mdx

+13-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ systray.SetTemplateIcon(iconBytes)
5656

5757
For more details on creating template icons, read this [great article](https://bjango.com/articles/designingmenubarextras/).
5858

59+
## Setting the Tooltip <Badge text="Windows" variant="note" />
60+
61+
You can set a tooltip for your system tray icon that appears when hovering over the icon:
62+
63+
```go
64+
systray.SetTooltip("My Application Tooltip")
65+
```
66+
5967
## Setting the Label <Badge text="macOS" variant="success" />
6068

6169
You can set a text label for your system tray icon:
@@ -66,6 +74,10 @@ systray.SetLabel("My App")
6674

6775
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.
6876

77+
:::note
78+
On Windows, setting the label is the equivalent of setting the tooltip.
79+
:::
80+
6981
## Adding a Menu
7082

7183
You can add a menu to your system tray icon:
@@ -172,6 +184,7 @@ Explore these examples for more advanced usage:
172184
| `NewSystemTray()` | Creates a new system tray instance |
173185
| `Run()` | Starts the system tray |
174186
| `SetLabel(label string)` | Sets the text label |
187+
| `SetTooltip(tooltip string)` | Sets the tooltip text (Windows) |
175188
| `SetIcon(icon []byte)` | Sets the icon image |
176189
| `SetDarkModeIcon(icon []byte)` | Sets the dark mode variant of the icon |
177190
| `SetTemplateIcon(icon []byte)` | Marks the icon as a template image (macOS) |
@@ -208,4 +221,3 @@ Explore these examples for more advanced usage:
208221
|----------|-----------------------------|
209222
| `Show()` | Makes the tray icon visible |
210223
| `Hide()` | Hides the tray icon |
211-

v3/examples/systray-custom/main.go

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ func main() {
5656
app.Quit()
5757
})
5858
systemTray.SetMenu(menu)
59+
systemTray.SetTooltip("Systray Demo")
5960

6061
if runtime.GOOS == "darwin" {
6162
systemTray.SetTemplateIcon(icons.SystrayMacTemplate)

v3/pkg/application/systemtray.go

+13
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const (
2525

2626
type systemTrayImpl interface {
2727
setLabel(label string)
28+
setTooltip(tooltip string)
2829
run()
2930
setIcon(icon []byte)
3031
setMenu(menu *Menu)
@@ -43,6 +44,7 @@ type systemTrayImpl interface {
4344
type SystemTray struct {
4445
id uint
4546
label string
47+
tooltip string
4648
icon []byte
4749
darkModeIcon []byte
4850
iconPosition IconPosition
@@ -67,6 +69,7 @@ func newSystemTray(id uint) *SystemTray {
6769
result := &SystemTray{
6870
id: id,
6971
label: "",
72+
tooltip: "",
7073
iconPosition: NSImageLeading,
7174
attachedWindow: WindowAttachConfig{
7275
Window: nil,
@@ -183,6 +186,16 @@ func (s *SystemTray) SetTemplateIcon(icon []byte) *SystemTray {
183186
return s
184187
}
185188

189+
func (s *SystemTray) SetTooltip(tooltip string) {
190+
if s.impl == nil {
191+
s.tooltip = tooltip
192+
return
193+
}
194+
InvokeSync(func() {
195+
s.impl.setTooltip(tooltip)
196+
})
197+
}
198+
186199
func (s *SystemTray) Destroy() {
187200
globalApplication.destroySystemTray(s)
188201
}

v3/pkg/application/systemtray_darwin.go

+4
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ func (s *macosSystemTray) setTemplateIcon(icon []byte) {
189189
})
190190
}
191191

192+
func (s *macosSystemTray) setTooltip(tooltip string) {
193+
// Tooltips not supported on macOS
194+
}
195+
192196
func newSystemTrayImpl(s *SystemTray) systemTrayImpl {
193197
result := &macosSystemTray{
194198
parent: s,

v3/pkg/application/systemtray_linux.go

+18-5
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ Portions of this code are derived from the project:
66
*/
77
package application
88

9+
import "C"
910
import (
1011
"fmt"
11-
"os"
12-
1312
"github.com/godbus/dbus/v5"
1413
"github.com/godbus/dbus/v5/introspect"
1514
"github.com/godbus/dbus/v5/prop"
1615
"github.com/wailsapp/wails/v3/internal/dbus/menu"
1716
"github.com/wailsapp/wails/v3/internal/dbus/notifier"
1817
"github.com/wailsapp/wails/v3/pkg/icons"
18+
"os"
1919
)
2020

2121
const (
@@ -31,7 +31,7 @@ type linuxSystemTray struct {
3131
icon []byte
3232
menu *Menu
3333

34-
iconPosition int
34+
iconPosition IconPosition
3535
isTemplateIcon bool
3636

3737
quitChan chan struct{}
@@ -41,6 +41,7 @@ type linuxSystemTray struct {
4141

4242
menuVersion uint32 // need to bump this anytime we change anything
4343
itemMap map[int32]*systrayMenuItem
44+
tooltip string
4445
}
4546

4647
func (s *linuxSystemTray) getScreen() (*Screen, error) {
@@ -103,9 +104,9 @@ func (s *systrayMenuItem) setHidden(hidden bool) {
103104
s.sysTray.update(s)
104105
}
105106

106-
func (i systrayMenuItem) dbus() *dbusMenu {
107+
func (s *systrayMenuItem) dbus() *dbusMenu {
107108
item := &dbusMenu{
108-
V0: int32(i.menuItem.id),
109+
V0: int32(s.menuItem.id),
109110
V1: map[string]dbus.Variant{},
110111
V2: []dbus.Variant{},
111112
}
@@ -364,9 +365,21 @@ func (s *linuxSystemTray) run() {
364365
}
365366
}
366367
}()
368+
369+
if s.parent.label != "" {
370+
s.setLabel(s.parent.label)
371+
}
372+
373+
if s.parent.tooltip != "" {
374+
s.setTooltip(s.parent.tooltip)
375+
}
367376
s.setMenu(s.menu)
368377
}
369378

379+
func (s *linuxSystemTray) setTooltip(_ string) {
380+
// TBD
381+
}
382+
370383
func (s *linuxSystemTray) setIcon(icon []byte) {
371384

372385
s.icon = icon

v3/pkg/application/systemtray_windows.go

+31-3
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,10 @@ func (s *windowsSystemTray) run() {
223223
s.updateMenu(s.parent.menu)
224224
}
225225

226+
if s.parent.tooltip != "" {
227+
s.setTooltip(s.parent.tooltip)
228+
}
229+
226230
// Set Default Callbacks
227231
if s.parent.clickHandler == nil {
228232
s.parent.clickHandler = func() {
@@ -367,12 +371,36 @@ func (s *windowsSystemTray) updateMenu(menu *Menu) {
367371
s.menu.Update()
368372
}
369373

370-
// ---- Unsupported ----
374+
// Based on the idea from https://github.com/wailsapp/wails/issues/3487#issuecomment-2633242304
375+
func (s *windowsSystemTray) setTooltip(tooltip string) {
376+
// Ensure the tooltip length is within the limit (64 characters for szTip)
377+
if len(tooltip) > 64 {
378+
tooltip = tooltip[:64]
379+
}
371380

372-
func (s *windowsSystemTray) setLabel(_ string) {
373-
// Unsupported - do nothing
381+
// Create a new NOTIFYICONDATA structure
382+
nid := s.newNotifyIconData()
383+
nid.UFlags = w32.NIF_TIP
384+
tooltipUTF16, err := w32.StringToUTF16(tooltip)
385+
if err != nil {
386+
return
387+
}
388+
389+
copy(nid.SzTip[:], tooltipUTF16)
390+
391+
// Modify the tray icon with the new tooltip
392+
if !w32.ShellNotifyIcon(w32.NIM_MODIFY, &nid) {
393+
return
394+
}
395+
nid.UVersion = 3 // Version 4 does not suport
396+
if !w32.ShellNotifyIcon(w32.NIM_SETVERSION, &nid) {
397+
return
398+
}
374399
}
375400

401+
// ---- Unsupported ----
402+
func (s *windowsSystemTray) setLabel(label string) {}
403+
376404
func (s *windowsSystemTray) setTemplateIcon(_ []byte) {
377405
// Unsupported - do nothing
378406
}

v3/pkg/w32/window.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ func MustStringToUTF16(input string) []uint16 {
191191
return lo.Must(syscall.UTF16FromString(input))
192192
}
193193

194+
func StringToUTF16(input string) ([]uint16, error) {
195+
input = stripNulls(input)
196+
return syscall.UTF16FromString(input)
197+
}
198+
194199
func CenterWindow(hwnd HWND) {
195200
windowInfo := getWindowInfo(hwnd)
196201
frameless := windowInfo.IsPopup()
@@ -329,7 +334,10 @@ func FindWindowW(className, windowName *uint16) HWND {
329334

330335
func SendMessageToWindow(hwnd HWND, msg string) {
331336
// Convert data to UTF16 string
332-
dataUTF16 := MustStringToUTF16(msg)
337+
dataUTF16, err := StringToUTF16(msg)
338+
if err != nil {
339+
return
340+
}
333341

334342
// Prepare COPYDATASTRUCT
335343
cds := COPYDATASTRUCT{

0 commit comments

Comments
 (0)