Skip to content

Notify backends of updates to plot render settings #7450

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
May 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f469a91
Add event for plot render settings
lionel- Mar 28, 2025
3857d4d
Draft request UI backend notification
lionel- Apr 15, 2025
62beb5c
Add subscription types
lionel- Apr 22, 2025
8f6950c
Notify interested backends
lionel- Apr 22, 2025
b432d5c
Invert dependencies between services
lionel- Apr 23, 2025
7a0ea79
Ensure handler is called on already started UI clients
lionel- Apr 24, 2025
f327e06
Add `register()` method to UI client instances for lifecycle management
lionel- Apr 24, 2025
50a5920
Fix import imbroglio
lionel- Apr 24, 2025
f400899
Add justfile for comms
lionel- Apr 25, 2025
03727b3
Homogenize naming
lionel- Apr 25, 2025
1df14b4
Second pass at exports conundrum
lionel- Apr 25, 2025
3c3d7fd
Add support for external references in OpenRPC contracts
lionel- Apr 25, 2025
6d41c27
Make notification a request for now
lionel- Apr 30, 2025
9452abb
Fix merge issues
lionel- May 1, 2025
65eb61f
Import external refs rather than redefine them
lionel- May 1, 2025
9d61cbf
Tweak doc
lionel- May 1, 2025
fc3df50
Fix comparison of settings
lionel- May 5, 2025
34b7aff
Fix dependencies in `useEffect()`
lionel- May 5, 2025
746fd38
Be defensive against invalid sizes
lionel- May 5, 2025
07e7628
Notify of render settings with current policy
lionel- May 6, 2025
f0864c1
Fix lifecycle issues with plot clients
lionel- May 6, 2025
a37322f
Update current sizing policy when plot policy changes
lionel- May 6, 2025
6b40f05
Add `onDidChangesizingPolicy` event on plot service
lionel- May 6, 2025
24a181a
Notify backends of sizing policy changes
lionel- May 6, 2025
ee08be3
Retrieve window from component
lionel- May 13, 2025
16c4ec8
Actually dispose the disposables
lionel- May 13, 2025
834f5ce
Fix result name
lionel- May 13, 2025
3601ed5
Actually run handler when UI client comes later
lionel- May 13, 2025
065b6cb
Bump Ark to 0.1.184
lionel- May 15, 2025
0035652
Merge branch 'main' into feature/update-plot-policy
lionel- May 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions extensions/positron-python/python_files/posit/positron/plot_comm.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,20 @@


@enum.unique
class RenderFormat(str, enum.Enum):
class PlotUnit(str, enum.Enum):
"""
Possible values for PlotUnit
"""

Pixels = "pixels"

Inches = "inches"


@enum.unique
class PlotRenderFormat(str, enum.Enum):
"""
Possible values for RenderFormat
Possible values for PlotRenderFormat
"""

Png = "png"
Expand All @@ -35,17 +46,6 @@ class RenderFormat(str, enum.Enum):
Tiff = "tiff"


@enum.unique
class PlotUnit(str, enum.Enum):
"""
Possible values for PlotUnit
"""

Pixels = "pixels"

Inches = "inches"


class IntrinsicSize(BaseModel):
"""
The intrinsic size of a plot, if known
Expand Down Expand Up @@ -81,9 +81,9 @@ class PlotResult(BaseModel):
description="The MIME type of the plot data",
)

policy: Optional[RenderPolicy] = Field(
settings: Optional[PlotRenderSettings] = Field(
default=None,
description="The policy used to render the plot",
description="The settings used to render the plot",
)


Expand All @@ -101,21 +101,21 @@ class PlotSize(BaseModel):
)


class RenderPolicy(BaseModel):
class PlotRenderSettings(BaseModel):
"""
The policy used to render the plot
The settings used to render the plot
"""

size: PlotSize = Field(
description="Plot size of the render policy",
description="Plot size to render the plot to",
)

pixel_ratio: Union[StrictInt, StrictFloat] = Field(
description="The pixel ratio of the display device",
)

format: RenderFormat = Field(
description="Format of the render policy",
format: PlotRenderFormat = Field(
description="Format in which to render the plot",
)


Expand Down Expand Up @@ -163,7 +163,7 @@ class RenderParams(BaseModel):
description="The pixel ratio of the display device",
)

format: RenderFormat = Field(
format: PlotRenderFormat = Field(
description="The requested plot format",
)

Expand Down Expand Up @@ -215,7 +215,7 @@ class PlotFrontendEvent(str, enum.Enum):

PlotSize.update_forward_refs()

RenderPolicy.update_forward_refs()
PlotRenderSettings.update_forward_refs()

GetIntrinsicSizeRequest.update_forward_refs()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def verify_response(response, filename: str, expected_size: Tuple[float, float],
assert percent_difference(image.size[1], expected_size[1] * pixel_ratio) <= threshold

# Check the rest of the response.
assert response == json_rpc_response({"mime_type": f"image/{format_}", "policy": None})
assert response == json_rpc_response({"mime_type": f"image/{format_}", "settings": None})

verify_response(response, "test-mpl-render-0-explicit-size", (size.width, size.height))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

from ._vendor.pydantic import BaseModel, Field, StrictBool, StrictFloat, StrictInt, StrictStr

from .plot_comm import PlotRenderSettings

Param = Any
CallMethodResult = Any

Expand Down Expand Up @@ -137,10 +139,47 @@ class UiBackendRequest(str, enum.Enum):
An enumeration of all the possible requests that can be sent to the backend ui comm.
"""

# Notification that the settings to render a plot (i.e. the plot size)
# have changed.
DidChangePlotsRenderSettings = "did_change_plots_render_settings"

# Run a method in the interpreter and return the result to the frontend
CallMethod = "call_method"


class DidChangePlotsRenderSettingsParams(BaseModel):
"""
Typically fired when the plot component has been resized by the user.
This notification is useful to produce accurate pre-renderings of
plots.
"""

settings: PlotRenderSettings = Field(
description="Plot rendering settings.",
)


class DidChangePlotsRenderSettingsRequest(BaseModel):
"""
Typically fired when the plot component has been resized by the user.
This notification is useful to produce accurate pre-renderings of
plots.
"""

params: DidChangePlotsRenderSettingsParams = Field(
description="Parameters to the DidChangePlotsRenderSettings method",
)

method: Literal[UiBackendRequest.DidChangePlotsRenderSettings] = Field(
description="The JSON-RPC method name (did_change_plots_render_settings)",
)

jsonrpc: str = Field(
default="2.0",
description="The JSON-RPC version specifier",
)


class CallMethodParams(BaseModel):
"""
Unlike other RPC methods, `call_method` calls into methods implemented
Expand Down Expand Up @@ -180,7 +219,10 @@ class CallMethodRequest(BaseModel):

class UiBackendMessageContent(BaseModel):
comm_id: str
data: CallMethodRequest
data: Union[
DidChangePlotsRenderSettingsRequest,
CallMethodRequest,
] = Field(..., discriminator="method")


@enum.unique
Expand Down Expand Up @@ -477,6 +519,10 @@ class ShowHtmlFileParams(BaseModel):

Range.update_forward_refs()

DidChangePlotsRenderSettingsParams.update_forward_refs()

DidChangePlotsRenderSettingsRequest.update_forward_refs()

CallMethodParams.update_forward_refs()

CallMethodRequest.update_forward_refs()
Expand Down
2 changes: 1 addition & 1 deletion extensions/positron-r/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@
},
"positron": {
"binaryDependencies": {
"ark": "0.1.183"
"ark": "0.1.184"
},
"minimumRVersion": "4.2.0",
"minimumRenvVersion": "1.0.9"
Expand Down
4 changes: 4 additions & 0 deletions extensions/positron-r/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,9 @@ export async function makeMetadata(
config.get<string>('shutdownTimeout', 'immediately') !== 'immediately' ?
positron.LanguageRuntimeSessionLocation.Machine : positron.LanguageRuntimeSessionLocation.Workspace;

// Subscribe to UI notifications of interest
const uiSubscriptions = [positron.UiRuntimeNotifications.DidChangePlotsRenderSettings];

const metadata: positron.LanguageRuntimeMetadata = {
runtimeId,
runtimeName,
Expand All @@ -295,6 +298,7 @@ export async function makeMetadata(
).toString('base64'),
sessionLocation,
startupBehavior,
uiSubscriptions,
extraRuntimeData
};

Expand Down
14 changes: 13 additions & 1 deletion positron/comms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,16 @@ npm install
If you've already installed dependencies, just run the code generator.
This will (re-)generate code for all comms.

```
```sh
npx ts-node generate-comms.ts
```

If you have `just` installed, then just run `just`:

```sh
just
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just easier to remember :-)

```

For each contract, this writes Rust, Python, and Typescript modules using the current contract.
It also prints each affected filepath.

Expand All @@ -82,6 +88,12 @@ This will (re-)generate code only for the ui and variables comms.
npx ts-node generate-comms.ts ui variables
```

You can pass arguments via `just` as well but you'll need to explicitly name the `gen` recipe instead of relying on it being the default:

```
just gen ui variables
```

Above we've targetted two comms by name, "ui" and "variables".
It's also acceptable to specify a comm by mentioning any member of its trio of files, i.e. "ui.json", "ui-frontend-openrpc.json", and "ui-backend-openrpc.json" are the same as specifying "ui".

Expand Down
Loading
Loading