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

[feat] [macOS] Configure acceptsFirstMouse for specific elements #4316

Open
probablykasper opened this issue Jun 10, 2022 · 16 comments
Open
Labels
platform: macOS status: backlog Issue is ready and we can work on it status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes type: feature request

Comments

@probablykasper
Copy link
Member

probablykasper commented Jun 10, 2022

Describe the bug

Elements with data-tauri-drag-region can't be dragged while the window isn't in focus, which is not how native windows (or Electron's implementation) works

Note: acceptsFirstMouse doesn't entirely solve this because that would also make everything in the window clickable

Reproduction

No response

Expected behavior

No response

Platform and versions

Environment
  › OS: Mac OS 10.15.7 X64
  › Node.js: 16.15.0
  › npm: 8.12.1
  › pnpm: Not installed!
  › yarn: Not installed!
  › rustup: 1.24.3
  › rustc: 1.61.0
  › cargo: 1.61.0
  › Rust toolchain: stable-x86_64-apple-darwin 

Packages
  › @tauri-apps/cli [NPM]: 1.0.0-rc.12 (outdated, latest: 1.0.0-rc.13)
  › @tauri-apps/api [NPM]: 1.0.0-rc.6
  › tauri [RUST]: git+https://github.com/tauri-apps/tauri?branch=mac-app-hide#ade64c9b1695043c40ffccb3a38b11d1a7f1b6bb (1.0.0-rc.12),
  › tauri-build [RUST]: 1.0.0-rc.10,
  › tao [RUST]: 0.9.1,
  › wry [RUST]: 0.17.0,

App
  › build-type: bundle
  › CSP: default-src 'self'; img-src *
  › distDir: ../build
  › devPath: http://localhost:9000/
  › framework: Svelte

App directory structure
  ├─ node_modules
  ├─ public
  ├─ .github
  ├─ src-tauri
  ├─ build
  ├─ .git
  ├─ assets
  └─ src

Stack trace

No response

Additional context

No response

@lhf6623
Copy link

lhf6623 commented Jun 15, 2022

I have this problem too,And Gaussian blur doesn't work when you lose focus

@dceddia
Copy link
Contributor

dceddia commented Jun 26, 2022

I ran into this too. I thought it might have something to do with the acceptsFirstMouse method.

It looks like at least tao is overriding that to be true here so it's probably taken care of at the window level, but I'm wondering if maybe it needs to be overridden for the WKWebView too. It looks like Electron overrides this:

This allows Electron to override acceptsFirstMouse on Mac so that windows can respond to the first mouse click in their window, which is desirable for some kinds of utility windows.

It looks like wry already has a WryWebView that subclasses WKWebView and that might be a good place to put this override. It would be overzealous though, and then filtering of mouse clicks would need to happen somewhere or we'd end up in the reverse situation where the window shouldn't respond to the first mouse click in a lot of situations. I guess ideally it would be up to the application whether it accepts those clicks, but I'm not sure where that would go.

@probablykasper
Copy link
Member Author

Enabling acceptsFirstMouse would technically fix it, but then you get unconventional behavior (although some Electron apps do this)

If we're able to detect the first mouse click position, we would be able to forward it to the frontend to decide if the window should be dragged

@dceddia
Copy link
Contributor

dceddia commented Jun 26, 2022

If it were special-cased for only data-tauri-drag-region I think it'd break strategies like this one that make most of the window draggable, which would be a bummer. Maybe it could be made into an option, and do something like...

  • enable acceptsFirstMouse so that all clicks get passed through
  • add an acceptsFirstMouse tauri.conf config option to let the developer opt in to receiving those events, but default it to false so behavior is conventional by default
  • update the existing mousedown handler to check for a combo of window focus, the configurable firstMouse config, and whether the click was on a data-tauri-drag-region to decide whether to pass the event through

I think a system like that would still let the developer do their custom startDragging code, and also allow breaking convention for apps where that's desirable. From Apple's acceptsFirstMouse docs it sounds like the convention is to pass firstMouse through for certain types of elements, too. Just as a random example I notice that Chrome passes firstMouse through if you click on a browser tab, but not to elements on the page. It'd be neat to have that level of control in Tauri too.

@probablykasper
Copy link
Member Author

If it were special-cased for only data-tauri-drag-region I think it'd break strategies like this one that make most of the window draggable, which would be a bummer. Maybe it could be made into an option, and do something like...

I think the solution there is to have data-tauri-drag-region="self" that applies only to the element itself, not children

@amrbashir amrbashir changed the title [bug] data-tauri-drag-region requires focus on macOS [feat] [macOS] Add an option to configure acceptsFirstMouse Sep 30, 2022
@amrbashir
Copy link
Member

/upstream tauri-apps/tao

@tauri-apps tauri-apps bot added the status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes label Sep 30, 2022
@amrbashir amrbashir added good first issue Good for newcomers and removed type: bug labels Sep 30, 2022
@tauri-apps
Copy link

tauri-apps bot commented Oct 3, 2022

Upstream issue at tauri-apps/tao#575 has been closed.

@tauri-apps tauri-apps bot added status: backlog Issue is ready and we can work on it and removed status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes labels Oct 3, 2022
@amrbashir amrbashir removed status: backlog Issue is ready and we can work on it good first issue Good for newcomers labels Oct 3, 2022
@amrbashir
Copy link
Member

/upstream tauri-apps/wry

@tauri-apps tauri-apps bot added the status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes label Oct 3, 2022
@tauri-apps
Copy link

tauri-apps bot commented Oct 4, 2022

Upstream issue at tauri-apps/wry#714 has been closed.

@tauri-apps tauri-apps bot added status: backlog Issue is ready and we can work on it and removed status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes labels Oct 4, 2022
@probablykasper probablykasper changed the title [feat] [macOS] Add an option to configure acceptsFirstMouse [feat] [macOS] Handle data-tauri-drag-region when unfocused Oct 4, 2022
@probablykasper probablykasper changed the title [feat] [macOS] Handle data-tauri-drag-region when unfocused [feat] [macOS] Configure acceptsFirstMouse for specific elements Oct 4, 2022
@probablykasper
Copy link
Member Author

Opened #5347 for exposing acceptsFirstMouse

@amrbashir
Copy link
Member

/upstream tauri-apps/wry

@tauri-apps tauri-apps bot added the status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes label Oct 4, 2022
@github-project-automation github-project-automation bot moved this to 📬Proposal in Roadmap Sep 26, 2023
@xyhcode
Copy link

xyhcode commented Aug 12, 2024

Setting acceptFirstMouse to true will not allow drag on Macs

    decorations: false,
    transparent: true,

@GafelSon
Copy link

GafelSon commented Sep 10, 2024

I'm not entirely sure if this solution will work for everyone, but it successfully resolved the issue in my case. The problem I was encountering involved dragging a window in a Tauri app on macOS, particularly when using the titleBarStyle: Overlay option, where dragging was not functioning as expected. !(Tauri + next.js)

But, through some trial and error (mostly error), I came up with this temporary hack...I mean, solution!

[dependencies]
tauri = { version = "1.7.2", features = ["macos-private-api", "api-all"] }

The macos-private-api and api-all features enable the macOS private APIs needed for handling native behavior more flexibly.

  1. Configure tauri.config.json
    In your tauri.config.json file, make sure to allow necessary permissions and enable dragging behavior with the startDragging option. Additionally, you can configure window properties, including the titleBarStyle set to Overlay.
{
  "tauri": {
    "allowlist": {
      "all": true,
      "window": {
        "startDragging": true
      }
    },
    "macOSPrivateApi": true,
    "windows": [
      {
        "fullscreen": false,
        "resizable": false,
        "height": 600,
        "width": 410,
        "title": "",
        "titleBarStyle": "Overlay"
      }
    ]
  }
}
  1. Implement TitleBarHandler
    This is the main logic for setting up the drag region. When the mouse is within the top 50px of the window, the drag region is activated. This allows the window to be draggable, mimicking the behavior of native macOS windows:
"use client";

import { useEffect } from "react";

const TitleBarHandler = () => {
  useEffect(() => {
    const handleMouseMove = (event) => {
      if (event.clientY >= 0 && event.clientY <= 50) {
        document.documentElement.setAttribute("data-tauri-drag-region", "true");
      } else {
        document.documentElement.removeAttribute("data-tauri-drag-region");
      }
    };

    window.addEventListener("mousemove", handleMouseMove);

    return () => {
      window.removeEventListener("mousemove", handleMouseMove);
      document.documentElement.removeAttribute("data-tauri-drag-region"); // Clean up when unmounting
    };
  }, []);

  return null; // No need to render anything for the title bar
};

export default TitleBarHandler;
  1. Handling Title Bar in React
    In your React component, you can create a custom handler to manage the drag region. For example, I imported a TitleBarHandler component that will handle the mouse move events and set the drag region dynamically based on the mouse position:
import TitleBarHandler from "../components/titleBarHandler";

export default function RootLayout({ children }) {
  return (
    <html lang='en'>
      <body>
        <TitleBarHandler /> {/* Import handler */}
        {children}
      </body>
    </html>
  );
}
.titlebar {
  height: 50px;
  user-select: none;
  display: flex;
  justify-content: flex-end;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}
.titlebar-button {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  width: 30px;
  height: 30px;
}

@nyssance
Copy link

nyssance commented Oct 5, 2024

我不确定这个解决方案是否适用于所有者,但它成功解决了我的问题。我完全遇到的问题涉及 macOS 上的 Tauri 应用程序中的拖动窗口,特别是在使用该titleBarStyle: Overlay选项时,拖动功能无法按预期运行。!(Tauri + next.js)

但是,通过反复试验(大部分是错误),我想出了这个临时解决办法……我的意思是,解决方案!

[dependencies]
tauri = { version = "1.7.2", features = ["macos-private-api", "api-all"] }

macos-private-api和功能api-all使处理本机所需的 macOS 真空 API 更加灵活。

  1. 配置tauri.config.json
    在您的tauri.config.json文件中,确保允许必要的权限并使用startDragging选项启用拖动行为。此外,您可以配置窗口属性,包括设置titleBarStyleOverlay
{
  "tauri": {
    "allowlist": {
      "all": true,
      "window": {
        "startDragging": true
      }
    },
    "macOSPrivateApi": true,
    "windows": [
      {
        "fullscreen": false,
        "resizable": false,
        "height": 600,
        "width": 410,
        "title": "",
        "titleBarStyle": "Overlay"
      }
    ]
  }
}
  1. 这是允许设置拖动区域的主要逻辑。当鼠标位于窗口顶部 50px 内时,拖动区域被激活。这个窗口TitleBarHandler
    可拖动,实现复制 macOS 窗口的行为:
"use client";

import { useEffect } from "react";

const TitleBarHandler = () => {
  useEffect(() => {
    const handleMouseMove = (event) => {
      if (event.clientY >= 0 && event.clientY <= 50) {
        document.documentElement.setAttribute("data-tauri-drag-region", "true");
      } else {
        document.documentElement.removeAttribute("data-tauri-drag-region");
      }
    };

    window.addEventListener("mousemove", handleMouseMove);

    return () => {
      window.removeEventListener("mousemove", handleMouseMove);
      document.documentElement.removeAttribute("data-tauri-drag-region"); // Clean up when unmounting
    };
  }, []);

  return null; // No need to render anything for the title bar
};

export default TitleBarHandler;
  1. 在 React 中标题处理栏
    在 React 组件中,您可以创建自定义处理程序来管理拖动区域。例如,我导入了一个TitleBarHandler组件,将处理鼠标移动事件并根据鼠标位置动态设置拖动区域:
import TitleBarHandler from "../components/titleBarHandler";

export default function RootLayout({ children }) {
  return (
    <html lang='en'>
      <body>
        <TitleBarHandler /> {/* Import handler */}
        {children}
      </body>
    </html>
  );
}
.titlebar {
  height: 50px;
  user-select: none;
  display: flex;
  justify-content: flex-end;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}
.titlebar-button {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  width: 30px;
  height: 30px;
}

How to work with Tauri 2.0?

@ericschmar
Copy link

#4316 (comment)

This configuration isn't compatible with Tauri v2.0 however the issue is persistent. Any ideas?

@GafelSon
Copy link

GafelSon commented Oct 12, 2024

#4316 (comment)

This configuration isn't compatible with Tauri v2.0 however the issue is persistent. Any ideas?

Yeah, the config won’t work with Tauri v2.0 because of some changes, but I figured out a way around it. Here’s what I did:

I used the recommended Tauri framework setup along with vanilla JavaScript

[dependencies]
cocoa = "0.25"
tauri = { version = "2.0.0", features = ["macos-private-api"] }

tauri.conf.json:

"app": {
   "macOSPrivateApi": true,
   "windows": [],
...
}

Here’s the code I used to set up the custom drag area and macOS title bar [./src/styles.css]:

.dragble-state {
  width: 100%;
  height: 1.75rem;
  position: fixed;
  user-select: none;
  display: flex;
  justify-content: flex-end;
  top: 0;
  left: 0;
}

[./src/main.ts]:

document.addEventListener("DOMContentLoaded", () => {
  const dragRegionDiv = document.createElement("div");
  dragRegionDiv.setAttribute("data-tauri-drag-region", "");
  dragRegionDiv.className = "dragble-state";
  document.documentElement.insertBefore(dragRegionDiv, document.body);
});

[./src-tauri/capabilities/default.json]:

{
...
"permissions": ["core:window:default", "core:window:allow-start-dragging"]
}

[./src-tauri/src/lib.rs]

pub fn run() {
    tauri::Builder::default()
        .setup(|app| {
            let win_builder = WebviewWindowBuilder::new(app, "main", WebviewUrl::default())
                .hidden_title(true)
                .inner_size(800.0, 600.0);

            #[cfg(target_os = "macos")]
            let win_builder = win_builder.title_bar_style(TitleBarStyle::Overlay);
            let _window = win_builder.build().unwrap();

            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

This setup works fine for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform: macOS status: backlog Issue is ready and we can work on it status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes type: feature request
Projects
Status: 📬Proposal
Development

No branches or pull requests

8 participants