Skip to content

Commit

Permalink
V3 alpha - calling window id and name (wailsapp#3888)
Browse files Browse the repository at this point in the history
* Add the calling window name and ID to the context if available. Update the documentation.

* Update changelog.md
  • Loading branch information
leaanthony authored Nov 19, 2024
1 parent a98bf32 commit d6866f6
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
2 changes: 2 additions & 0 deletions mkdocs-website/docs/en/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- New `InitialPosition` option to specify if the window should be centered or positioned at the given X/Y location by [leaanthony](https://github.com/leaanthony) in [#3885](https://github.com/wailsapp/wails/pull/3885)
- Add `Path` & `Paths` methods to `application` package by [ansxuman](https://github.com/ansxuman) and [leaanthony](https://github.com/leaanthony) in [#3823](https://github.com/wailsapp/wails/pull/3823)
- Added `GeneralAutofillEnabled` and `PasswordAutosaveEnabled` Windows options by [leaanthony](https://github.com/leaanthony) in [#3766](https://github.com/wailsapp/wails/pull/3766)
- Added the ability to retrieve the window calling a service method by [leaanthony](https://github.com/leaanthony)
in [#3888](https://github.com/wailsapp/wails/pull/3888)

### Changed
- Asset embed to include `all:frontend/dist` to support frameworks that generate subfolders by @atterpac in [#3887](https://github.com/wailsapp/wails/pull/3887)
Expand Down
47 changes: 47 additions & 0 deletions mkdocs-website/docs/en/learn/bindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,3 +329,50 @@ export class Person {
```
Using TypeScript bindings provides type safety and improved IDE support when working with the generated code in your frontend.
### Using `context.Context`
When defining service methods in Go, you can include `context.Context` as the first parameter. The runtime will automatically provide a context when the method is called from the frontend.
The context provides several powerful features:
1. **Cancellation Support**: Long-running operations can be cancelled from the frontend, which will raise an error through the Promise chain.
2. **Window Information**: You can determine which window made the call using these context keys:
- `application.WindowNameKey` - Returns the name of the calling window
- `application.WindowIDKey` - Returns the ID of the calling window
Here are some examples:
```go
// Basic context usage with cancellation
func (s *MyService) LongRunningTask(ctx context.Context, input string) (string, error) {
select {
// Check if the context has been cancelled from the frontend
case <-ctx.Done():
return "", ctx.Err()
default:
// Process task
return "completed", nil
}
}
// Getting caller window information
func (s *MyService) WindowAwareMethod(ctx context.Context) (string, error) {
windowName := ctx.Value(application.WindowNameKey).(string)
windowID := ctx.Value(application.WindowIDKey).(string)
return fmt.Sprintf("Called from window: %s (ID: %s)", windowName, windowID), nil
}
```
From the frontend, these methods can be called normally. If you need to cancel a long-running operation, the Promise will be rejected with the cancellation error:
```javascript
// Call the method
const promise = MyService.LongRunningTask("input");
// Cancel it later if needed
// This will cause the context to be cancelled in the Go method
promise.cancel();
```
18 changes: 16 additions & 2 deletions v3/pkg/application/messageprocessor_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ import (
"net/http"
)

type contextKey string

const (
CallBinding = 0
CallBinding = 0
WindowNameKey contextKey = "WindowName"
WindowIDKey contextKey = "WindowID"
)

func (m *MessageProcessor) callErrorCallback(window Window, message string, callID *string, err error) {
Expand Down Expand Up @@ -95,6 +99,12 @@ func (m *MessageProcessor) processCallMethod(method int, rw http.ResponseWriter,
return
}

// Set the context values for the window
if window != nil {
ctx = context.WithValue(ctx, WindowNameKey, window.Name())
ctx = context.WithValue(ctx, WindowIDKey, window.ID())
}

go func() {
defer func() {
cancel()
Expand Down Expand Up @@ -123,7 +133,11 @@ func (m *MessageProcessor) processCallMethod(method int, rw http.ResponseWriter,
var jsonArgs struct {
Args json.RawMessage `json:"args"`
}
params.ToStruct(&jsonArgs)
err = params.ToStruct(&jsonArgs)
if err != nil {
m.callErrorCallback(window, "Error parsing arguments: %s", callID, err)
return
}
m.Info("Call Binding:", "method", boundMethod, "args", string(jsonArgs.Args), "result", result)
}()
m.ok(rw)
Expand Down

0 comments on commit d6866f6

Please sign in to comment.