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

lib:border - del_border + does not work with “acceptFirstMouse”: true #141

Open
doroved opened this issue Oct 9, 2024 · 23 comments
Open
Assignees

Comments

@doroved
Copy link

doroved commented Oct 9, 2024

Hi Victor, can you tell me how to delete a border? The current solution doesn't work

        if data.is_pinned {
            window.add_border(Some(BorderConfig {
                line_width: 3.0,
                line_color: Color(36, 211, 238, 255),
                inset: 0.0,
                corner_radius: 12.0,
            }));
            window.border().unwrap().set_auto_resizing();
        } else {
            window.add_border(None);
        }

And it seems set_auto_resizing doesn't work, even if you specify it manually, border overlaps content if you specify for example line_width: 10.0.

Found another problem, "acceptFirstMouse": true stops working after setting add_border.
Looks like use tauri::Color; is not the correct use, use tauri::window::Color;.

@ahkohd
Copy link
Owner

ahkohd commented Oct 19, 2024

I added two new functions, BorderView.remove() & BorderView.set_accepts_first_mouse(value: bool).

See the PR: #149

usage:

let border = window.border().expect("window has no border");

// to accept the first mouse click
border.set_accepts_first_mouse(true);

// to remove the border from the parent view
border.remove();

I have renamed the tauri::Color type to tauri::window::Color in the documentation.

@ahkohd ahkohd self-assigned this Oct 19, 2024
@ahkohd
Copy link
Owner

ahkohd commented Oct 19, 2024

Let me know if this resolves your issue. Thank you.

@doroved
Copy link
Author

doroved commented Oct 30, 2024

Let me know if this resolves your issue. Thank you.

I tried different options but couldn't get this to work inside window.listen, if you use window_clone you get this error

thread 'tokio-runtime-worker' panicked at src/main.rs:507:44:
window has no border

If you set the border inside window.listen, it works incorrectly and at each triggering event parameters of color, thickness, etc. are not set, set_accepts_first_mouse triggers only the first time, then stops, apparently because of the repeated setting there is a conflict.

fn switch_to_panel(app_handle: &AppHandle) {
    let window = app_handle.get_webview_window("main").unwrap();
    let panel = window.to_panel().unwrap();

    let delegate = panel_delegate!(MyPanelDelegate {
        window_did_become_key,
        window_did_resign_key,
    });

    window.add_border(None);
    let border = window.border().expect("window has no border");
    border.set_accepts_first_mouse(true);

    let window_clone = window.clone();

    window.listen("window:pin:toggle", move |event| {
        let border = window_clone.border().expect("window has no border");

        if data.is_pinned {
            border.set_accepts_first_mouse(true);
            border.set_line_width(3.0);
            border.set_line_color(Color(36, 211, 238, 255));
            border.set_inset(0.0);
            border.set_corner_radius(12.0);
        } else {
            border.remove();
        }

    }
....

@ahkohd
Copy link
Owner

ahkohd commented Oct 30, 2024

try and send it to the main thread. do all the window appearance stuff on the main thread:

app_handle.run_on_main_thread()

@doroved
Copy link
Author

doroved commented Oct 30, 2024

try and send it to the main thread. do all the window appearance stuff on the main thread:

app_handle.run_on_main_thread()

I'm not quite sure where to use it

@ahkohd
Copy link
Owner

ahkohd commented Oct 30, 2024

try and send it to the main thread. do all the window appearance stuff on the main thread:

app_handle.run_on_main_thread()

I'm not quite sure where to use it

let handle = app_handle.clone();

 window.listen("window:pin:toggle", move |event| {
let app_handle = handle.clone();

handle.run_on_main_thread(move || {
let window = app_handle.get_webview_window("window name" );

  let border = window.border().expect("window has no border");

        if data.is_pinned {
            border.set_accepts_first_mouse(true);
            border.set_line_width(3.0);
            border.set_line_color(Color(36, 211, 238, 255));
            border.set_inset(0.0);
            border.set_corner_radius(12.0);
        } else {
            border.remove();
        }
});

    }

roughly like that. inside the window:pin:toggle callback, call app_handle.run_on_main_thread() passing the border stuffs as into it's fn arg

@doroved
Copy link
Author

doroved commented Oct 30, 2024

try and send it to the main thread. do all the window appearance stuff on the main thread:

app_handle.run_on_main_thread()

I'm not quite sure where to use it

let handle = app_handle.clone();

 window.listen("window:pin:toggle", move |event| {
let app_handle = handle.clone();

handle.run_on_main_thread(move || {
let window = app_handle.get_webview_window("window name" );

  let border = window.border().expect("window has no border");

        if data.is_pinned {
            border.set_accepts_first_mouse(true);
            border.set_line_width(3.0);
            border.set_line_color(Color(36, 211, 238, 255));
            border.set_inset(0.0);
            border.set_corner_radius(12.0);
        } else {
            border.remove();
        }
});

    }

roughly like that. inside the window:pin:toggle callback, call app_handle.run_on_main_thread() passing the border stuffs as into it's fn arg

It works only once, then at each event instead of the set color, the border is layered with gray color, I think there is a conflict because at each event the border is added window.add_border(None);.

@ahkohd
Copy link
Owner

ahkohd commented Oct 30, 2024

Since I don't have a clear picture of your code, I can suggest how I think it should work:

  1. Call window.add_border once with Some(config). In this config, set your border size and make the border transparent.
  2. In your window:pin:toggle, get the window's border and set the color to your desired solid color.
  3. Instead of removing the border, simply revert the color back to transparent.

@ahkohd
Copy link
Owner

ahkohd commented Oct 30, 2024

Also, keep in mind that the border.remove() function removes the border from the window's content view. However, it still exists, and you can assign it to a new parent.

image image

@ahkohd
Copy link
Owner

ahkohd commented Oct 30, 2024

you can always check if border already exits to prevent adding duplicates:

if window.border().is_none() {
   // add your border
    window.add_border(None);
}

@ahkohd
Copy link
Owner

ahkohd commented Oct 30, 2024

Reading how it works may help you understand:
image

Let me know how it goes.

@doroved
Copy link
Author

doroved commented Oct 30, 2024

you can always check if border already exits to prevent adding duplicates:

if window.border().is_none() {
   // add your border
    window.add_border(None);
}

Yes, this option works, thanks. Only it seems set_auto_resizing doesn't work because the border overlaps the content.

        let app_handle = handle.clone();

        let _ = handle.run_on_main_thread(move || {
            let window = app_handle.get_webview_window("main").unwrap();

            if window.border().is_none() {
                window.add_border(None);
            }

            let border = window.border().expect("window has no border");
            border.set_accepts_first_mouse(true);

            if data.is_pinned {
                border.set_line_width(5.0);
                border.set_line_color(Color(36, 211, 238, 255));
                border.set_inset(0.0);
                border.set_corner_radius(12.0);
                border.set_auto_resizing();
            } else {
                border.remove();
            }
        });

@ahkohd
Copy link
Owner

ahkohd commented Oct 31, 2024

you can always check if border already exits to prevent adding duplicates:

if window.border().is_none() {
   // add your border
    window.add_border(None);
}

Yes, this option works, thanks. Only it seems set_auto_resizing doesn't work because the border overlaps the content.

        let app_handle = handle.clone();

        let _ = handle.run_on_main_thread(move || {
            let window = app_handle.get_webview_window("main").unwrap();

            if window.border().is_none() {
                window.add_border(None);
            }

            let border = window.border().expect("window has no border");
            border.set_accepts_first_mouse(true);

            if data.is_pinned {
                border.set_line_width(5.0);
                border.set_line_color(Color(36, 211, 238, 255));
                border.set_inset(0.0);
                border.set_corner_radius(12.0);
                border.set_auto_resizing();
            } else {
                border.remove();
            }
        });

remove the border.remove() line, instead set the color to transparent.

@ahkohd
Copy link
Owner

ahkohd commented Oct 31, 2024

Since I don't have a clear picture of your code, I can suggest how I think it should work:

  1. Call window.add_border once with Some(config). In this config, set your border size and make the border transparent.
  2. In your window:pin:toggle, get the window's border and set the color to your desired solid color.
  3. Instead of removing the border, simply revert the color back to transparent.

this.

@ahkohd
Copy link
Owner

ahkohd commented Oct 31, 2024

I can implement a border.destroy() method. which will call border.remove() and destroy the border view.

@doroved
Copy link
Author

doroved commented Oct 31, 2024

I can implement a border.destroy() method. which will call border.remove() and destroy the border view.

This one will be better.

@ahkohd
Copy link
Owner

ahkohd commented Oct 31, 2024

I can implement a border.destroy() method. which will call border.remove() and destroy the border view.

This one will be better.

well, but not really, it's better to reuse objects than to create and destroy them every time.

@ahkohd
Copy link
Owner

ahkohd commented Oct 31, 2024

I can implement a border.destroy() method. which will call border.remove() and destroy the border view.

image

Here is the implementation, I haven't tested it.

@ahkohd
Copy link
Owner

ahkohd commented Oct 31, 2024

Here is the commit 44e3d9f. Help test it. Let me know how it goes.

run cargo update -p border

@doroved
Copy link
Author

doroved commented Oct 31, 2024

this.

If you remove border.remove(); the border stops being set at all, border.set_line_color(Color(36, 211, 238, 0)); solves nothing in this case.

@ahkohd
Copy link
Owner

ahkohd commented Oct 31, 2024

this.

If you remove border.remove(); the border stops being set at all, border.set_line_color(Color(36, 211, 238, 0)); solves nothing in this case.

I'm not sure how your setup is. However, I think you should only call window.add_border once!, when you create the window. Configure it's color to transparent at that point. When you pin your panel, change the color to a solid color. When you unpin it, set it back to transparent. I see no need for remove/destroy unless I'm missing something.

@doroved
Copy link
Author

doroved commented Oct 31, 2024

this.

If you remove border.remove(); the border stops being set at all, border.set_line_color(Color(36, 211, 238, 0)); solves nothing in this case.

I'm not sure how your setup is. However, I think you should only call window.add_border once!, when you create the window. Configure it's color to transparent at that point. When you pin your panel, change the color to a solid color. When you unpin it, set it back to transparent. I see no need for remove/destroy unless I'm missing something.

The color change just refuses to work. Only the initial border is set.set_line_color(Color(36, 211, 238, 255));

            let window = app_handle.get_webview_window("main").unwrap();
            window.add_border(None);
            let border = window.border().expect("window has no border");
            border.set_accepts_first_mouse(true);
            border.set_line_width(5.0);
            border.set_line_color(Color(36, 211, 238, 255));
            border.set_inset(0.0);
            border.set_corner_radius(12.0);
            border.set_auto_resizing();

            switch_to_panel(app_handle);
            setup_shortcut(app_handle);

            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("unable to run Tauri application");
...
        let app_handle = handle.clone();

        let _ = handle.run_on_main_thread(move || {
            let window = app_handle.get_webview_window("main").unwrap();

            let border = window.border().expect("window has no border");

            if data.is_pinned {
                border.set_line_color(Color(36, 111, 111, 111));
            } else {
               border.set_line_color(Color(56, 67, 145, 123));
            }
        });

@ahkohd
Copy link
Owner

ahkohd commented Oct 31, 2024

this.

If you remove border.remove(); the border stops being set at all, border.set_line_color(Color(36, 211, 238, 0)); solves nothing in this case.

I'm not sure how your setup is. However, I think you should only call window.add_border once!, when you create the window. Configure it's color to transparent at that point. When you pin your panel, change the color to a solid color. When you unpin it, set it back to transparent. I see no need for remove/destroy unless I'm missing something.

The color change just refuses to work. Only the initial border is set.set_line_color(Color(36, 211, 238, 255));

            let window = app_handle.get_webview_window("main").unwrap();
            window.add_border(None);
            let border = window.border().expect("window has no border");
            border.set_accepts_first_mouse(true);
            border.set_line_width(5.0);
            border.set_line_color(Color(36, 211, 238, 255));
            border.set_inset(0.0);
            border.set_corner_radius(12.0);
            border.set_auto_resizing();

            switch_to_panel(app_handle);
            setup_shortcut(app_handle);

            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("unable to run Tauri application");
...
        let app_handle = handle.clone();

        let _ = handle.run_on_main_thread(move || {
            let window = app_handle.get_webview_window("main").unwrap();

            let border = window.border().expect("window has no border");

            if data.is_pinned {
                border.set_line_color(Color(36, 111, 111, 111));
            } else {
               border.set_line_color(Color(56, 67, 145, 123));
            }
        });

I'll play around with this to see what's wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants