Skip to content
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

MNT/FEAT migrate to Tauri v2 & stay-on-bottom + click-through #49

Merged
merged 16 commits into from
Apr 29, 2024

Conversation

Charlie-XIAO
Copy link
Contributor

@Charlie-XIAO Charlie-XIAO commented Apr 28, 2024

Fixes #39.
Closes #43 (superceded), thanks @Xinyu-Li-123.

This PR bumps Tauri to v2. Run npm run setup to install the beta versions of dependencies and build for tooling. On Linux, additionally update to libwebkit2gtk-4.1-dev.

Reworking inlined plugins

Inlined plugins are only recently supported in v2 (due to the permission system) and do not have documentations yet; the only reference available is tauri-apps/tauri#8781. It seems that there are constraints that the only acceptable separator is -. To keep the namespace-like naming for our widget APIs, I decided to use apis-${module} to replace the original widget_api|${module}.

To extend widget APIs in the future, one need to go through the following steps:

  • Create src-tauri/src/apis/${module}/, where mod.rs defines an init function to build the plugin and apis.rs implements the actual commands. Other utility files are optional.
  • Create tooling/apis/src/${module}.ts that defines the frontend invokers of the commands.
  • Go to src-tauri/build.rs, add const WIDGET_APIS_${MODULE}_COMMANDS: &[&str] = &[...], then call an additional .plugin("apis-${module}", InlinedPlugin::new().commands(WIDGET_APIS_${MODULE}_COMMANDS)) on the build attributes.
  • Create src-tauri/permissions/apis-${module}/default.toml and include a default preset that allows all commands. Refer to the existing fs module if confused. Note that the underscores in commands should be changed to hyphens, e.g., a command hello_world should correspond to allow-hello-world in the permissions.
  • Go to src-tauri/capabilities/canvas.json, and add apis-${module}:default to permissions.

Reworking internal commands

With the changes above to support inlined plugins, internal commands seem to lose their permissions which should have been granted by default. To work around, one need to go through the following steps to create a new internal command:

  • Define the command in src-tauri/src/commands.rs. Make sure to place only commands in this file and separate utility functions elsewhere.
  • Go to src-tauri/src/main.rs and add the command name in generate_handler!.
  • Go to src-tauri/build.rs and add the command name in INTERNAL_COMMANDS. This should automatically generate the corresponding permission file src-tauri/permissions/autogenerated/${cmd}.toml because INTERNAL_COMMANDS are set in the application permission manifest. Consequently we are using tauri_build_context instead of generate_context now.
  • Go to src-tauri/capabilities/, find the correct ACL configuration file and add allow-${xxx} to permissions, where xxx is cmd with underlines converted to hyphens, as mentioned above.

Feature: always on bottom

This is the main reason why we migrated to Tauri v2. always_on_bottom is easy to implement for Linux and macOS with some platform-specific code, but for Windows this is hard because it does not provide an intrinsic API and have to interact with the lifecycle which we do not have full control of. In particular, the following is a working implementation:

Implementation

unsafe fn window_proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT {
    match msg {
        WM_WINDOWPOSCHANGING => {
            let window_pos = &mut *(lparam.0 as *mut WINDOWPOS);
            window_pos.hwndInsertAfter = HWND_BOTTOM;
            LRESULT(0)
        },
        _ => LRESULT(0),
    }
}

pub(crate) fn set_on_bottom(window: &Window) -> Result<(), Box<dyn std::error::Error>> {
    let hwnd = HWND(window.hwnd()?.0);
    unsafe {
        SetWindowPos(
            hwnd,
            HWND_BOTTOM,
            0,
            0,
            0,
            0,
            SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE,
        )?;
        let _ = InvalidateRgn(hwnd, HRGN::default(), false);
    }
    Ok(())
}

pub(crate) fn set_always_on_bottom(
    window: &Window,
) -> Result<(), Box<dyn std::error::Error>> {
    let hwnd = HWND(window.hwnd()?.0);
    unsafe {
        SetWindowLongPtrW(hwnd, GWLP_WNDPROC, window_proc as isize);
    }
    Ok(())
}

The problem is that it can break other important properties of the canvas because of interfering with TAO implementations, unless we implement everything directly with Windows API which is clearly infeasible.

Back to the topic, we currently implement the switch between click-through (can interact with desktop but cannot interact with widgets) and non-click-through (can interact with widgets but cannot interact with desktop). The toggling can be achieved in the following ways:

  • Left-click the tray icon. Note that this is not possible on Linux.
  • Use keyboard shortcut Ctrl/Cmd + Shift + H. We many support shortcut customization in the future, in case people need this shortcut for other usages.
  • Open the tray icon menu and click on "Sink"/"Float". Note how this text changes with the current state of the canvas.

Remaining issues

@Charlie-XIAO Charlie-XIAO changed the title MAINT migrate to Tauri v2 MNT/FEAT migrate to Tauri v2 & stay-on-bottom + click-through Apr 28, 2024
@Xinyu-Li-123 Xinyu-Li-123 marked this pull request as ready for review April 29, 2024 14:34
@Charlie-XIAO
Copy link
Contributor Author

Merging on CI green. This is a blocking PR, and none of the remaining issues listed in the top comment can be solved immediately, so we shall leave them to later PRs.

@Charlie-XIAO Charlie-XIAO merged commit 5f46df5 into main Apr 29, 2024
10 checks passed
@Charlie-XIAO Charlie-XIAO deleted the migrate-v2 branch April 29, 2024 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:maintenance General maintenance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FEAT sink the canvas window below desktop icons
3 participants