mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
fix(v3): Dock ops sync and add GetBadge method (#4838)
* dock fixes and get method * update changelog * async -> sync * cleanup iOS and darwin set call * handle potential errors
This commit is contained in:
parent
52d0b30549
commit
1a5c6dceee
7 changed files with 98 additions and 20 deletions
|
|
@ -131,6 +131,11 @@ Remove the badge from the application icon:
|
|||
dockService.RemoveBadge()
|
||||
```
|
||||
|
||||
### Getting the set badge
|
||||
```go
|
||||
dockService.GetBadge()
|
||||
```
|
||||
|
||||
## Platform Considerations
|
||||
|
||||
<Tabs>
|
||||
|
|
@ -220,6 +225,7 @@ dockService.RemoveBadge()
|
|||
| `SetBadge(label string) error` | Sets a badge with the specified label |
|
||||
| `SetCustomBadge(label string, options BadgeOptions) error` | Sets a badge with the specified label and custom styling options (Windows only) |
|
||||
| `RemoveBadge() error` | Removes the badge from the application icon |
|
||||
| `GetBadge() *string` | Gets the current badge |
|
||||
|
||||
### Structs and Types
|
||||
|
||||
|
|
|
|||
|
|
@ -17,12 +17,14 @@ After processing, the content will be moved to the main changelog and this file
|
|||
|
||||
## Added
|
||||
<!-- New features, capabilities, or enhancements -->
|
||||
- Add `GetBadge` method to the dock service
|
||||
|
||||
## Changed
|
||||
<!-- Changes in existing functionality -->
|
||||
|
||||
## Fixed
|
||||
<!-- Bug fixes -->
|
||||
- Fix dock badge methods consistency on macOS
|
||||
|
||||
## Deprecated
|
||||
<!-- Soon-to-be removed features -->
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ import (
|
|||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
|
||||
type iosDock struct{}
|
||||
type iosDock struct {
|
||||
}
|
||||
|
||||
// New creates a new Dock Service.
|
||||
// On iOS, this returns a stub implementation.
|
||||
|
|
@ -61,4 +62,10 @@ func (d *iosDock) SetCustomBadge(label string, options BadgeOptions) error {
|
|||
func (d *iosDock) RemoveBadge() error {
|
||||
// iOS badge removal would go here via native bridge
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetBadge retrieves the badge from the iOS app icon.
|
||||
func (d *iosDock) GetBadge() *string {
|
||||
// iOS badge retrieval would go here via native bridge
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ type platformDock interface {
|
|||
SetBadge(label string) error
|
||||
SetCustomBadge(label string, options BadgeOptions) error
|
||||
RemoveBadge() error
|
||||
GetBadge() *string
|
||||
}
|
||||
|
||||
// Service represents the dock service
|
||||
|
|
@ -75,3 +76,8 @@ func (d *DockService) SetCustomBadge(label string, options BadgeOptions) error {
|
|||
func (d *DockService) RemoveBadge() error {
|
||||
return d.impl.RemoveBadge()
|
||||
}
|
||||
|
||||
// GetBadge returns the badge label on the application icon.
|
||||
func (d *DockService) GetBadge() *string {
|
||||
return d.impl.GetBadge()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,42 +8,59 @@ package dock
|
|||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
void hideDockIcon() {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
|
||||
});
|
||||
}
|
||||
|
||||
void showDockIcon() {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
});
|
||||
}
|
||||
|
||||
static void setBadge(const char *label) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
bool setBadge(const char *label) {
|
||||
__block bool success = false;
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
// Ensure the app is in Regular activation policy (dock icon visible)
|
||||
NSApplicationActivationPolicy currentPolicy = [NSApp activationPolicy];
|
||||
if (currentPolicy != NSApplicationActivationPolicyRegular) {
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *nsLabel = nil;
|
||||
if (label != NULL) {
|
||||
nsLabel = [NSString stringWithUTF8String:label];
|
||||
}
|
||||
[[NSApp dockTile] setBadgeLabel:nsLabel];
|
||||
[[NSApp dockTile] display];
|
||||
success = true;
|
||||
});
|
||||
return success;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
|
||||
type darwinDock struct{}
|
||||
type darwinDock struct {
|
||||
mu sync.RWMutex
|
||||
Badge *string
|
||||
}
|
||||
|
||||
// Creates a new Dock Service.
|
||||
func New() *DockService {
|
||||
return &DockService{
|
||||
impl: &darwinDock{},
|
||||
impl: &darwinDock{
|
||||
Badge: nil,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -67,22 +84,42 @@ func (d *darwinDock) HideAppIcon() {
|
|||
}
|
||||
|
||||
// ShowAppIcon shows the app icon in the macOS Dock.
|
||||
// Note: After showing the dock icon, you may need to call SetBadge again
|
||||
// to reapply any previously set badge, as changing activation policies clears the badge.
|
||||
func (d *darwinDock) ShowAppIcon() {
|
||||
C.showDockIcon()
|
||||
}
|
||||
|
||||
// SetBadge sets the badge label on the application icon.
|
||||
func (d *darwinDock) SetBadge(label string) error {
|
||||
// Always pick a label (use “●” if empty), then allocate + free exactly once.
|
||||
value := label
|
||||
if value == "" {
|
||||
value = "●" // Default badge character
|
||||
}
|
||||
cLabel := C.CString(value)
|
||||
defer C.free(unsafe.Pointer(cLabel))
|
||||
// setBadge handles the C call and updates the internal badge state with locking.
|
||||
func (d *darwinDock) setBadge(label *string) error {
|
||||
var cLabel *C.char
|
||||
if label != nil {
|
||||
cLabel = C.CString(*label)
|
||||
defer C.free(unsafe.Pointer(cLabel))
|
||||
}
|
||||
|
||||
C.setBadge(cLabel)
|
||||
return nil
|
||||
success := C.setBadge(cLabel)
|
||||
if !success {
|
||||
return fmt.Errorf("failed to set badge")
|
||||
}
|
||||
|
||||
d.mu.Lock()
|
||||
d.Badge = label
|
||||
d.mu.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetBadge sets the badge label on the application icon.
|
||||
// Available default badge labels:
|
||||
// Single space " " empty badge
|
||||
// Empty string "" dot "●" indeterminate badge
|
||||
func (d *darwinDock) SetBadge(label string) error {
|
||||
// Always pick a label (use "●" if empty), then allocate + free exactly once.
|
||||
if label == "" {
|
||||
label = "●" // Default badge character
|
||||
}
|
||||
return d.setBadge(&label)
|
||||
}
|
||||
|
||||
// SetCustomBadge is not supported on macOS, SetBadge is called instead.
|
||||
|
|
@ -92,6 +129,12 @@ func (d *darwinDock) SetCustomBadge(label string, options BadgeOptions) error {
|
|||
|
||||
// RemoveBadge removes the badge label from the application icon.
|
||||
func (d *darwinDock) RemoveBadge() error {
|
||||
C.setBadge(nil)
|
||||
return nil
|
||||
return d.setBadge(nil)
|
||||
}
|
||||
|
||||
// GetBadge returns the badge label on the application icon.
|
||||
func (d *darwinDock) GetBadge() *string {
|
||||
d.mu.RLock()
|
||||
defer d.mu.RUnlock()
|
||||
return d.Badge
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,3 +68,8 @@ func (l *linuxDock) RemoveBadge() error {
|
|||
// No-op: Linux doesn't have standardized badge support
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *linuxDock) GetBadge() *string {
|
||||
// No-op: Linux doesn't have standardized badge support
|
||||
return nil
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ type windowsDock struct {
|
|||
badgeSize int
|
||||
fontManager *FontManager
|
||||
badgeOptions BadgeOptions
|
||||
badge *string
|
||||
}
|
||||
|
||||
var defaultOptions = BadgeOptions{
|
||||
|
|
@ -48,6 +49,7 @@ func NewWithOptions(options BadgeOptions) *DockService {
|
|||
return &DockService{
|
||||
impl: &windowsDock{
|
||||
badgeOptions: options,
|
||||
badge: nil,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -121,6 +123,7 @@ func (w *windowsDock) SetBadge(label string) error {
|
|||
}
|
||||
defer w32.DestroyIcon(hicon)
|
||||
|
||||
w.badge = &label
|
||||
return w.taskbar.SetOverlayIcon(hwnd, hicon, nil)
|
||||
})
|
||||
}
|
||||
|
|
@ -182,6 +185,7 @@ func (w *windowsDock) SetCustomBadge(label string, options BadgeOptions) error {
|
|||
}
|
||||
defer w32.DestroyIcon(hicon)
|
||||
|
||||
w.badge = &label
|
||||
return w.taskbar.SetOverlayIcon(hwnd, hicon, nil)
|
||||
})
|
||||
}
|
||||
|
|
@ -209,6 +213,7 @@ func (w *windowsDock) RemoveBadge() error {
|
|||
}
|
||||
hwnd := uintptr(nativeWindow)
|
||||
|
||||
w.badge = nil
|
||||
return w.taskbar.SetOverlayIcon(hwnd, 0, nil)
|
||||
})
|
||||
}
|
||||
|
|
@ -394,3 +399,7 @@ func (w *windowsDock) createBadge() {
|
|||
|
||||
w.badgeImg = img
|
||||
}
|
||||
|
||||
func (w *windowsDock) GetBadge() *string {
|
||||
return w.badge
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue