tauri-apps / tauri

Build smaller, faster, and more secure desktop and mobile applications with a web frontend.
https://tauri.app
Apache License 2.0
85.95k stars 2.6k forks source link

feat(linux): expose `gtk_window` method #2083

Closed reujab closed 3 years ago

reujab commented 3 years ago

Nice project, I'd love to make some desktop widgets for Linux using Tauri. Is there any way we could set the type hint on Linux and possibly use the layer shell API?

Describe alternatives you've considered Perhaps the developer could create their own modified window and pass it to Tauri or modify it in a closure?

nothingismagick commented 3 years ago

Thanks for the suggestion, but we are about to enter code freeze, and the core team won't be accepting non critical features for at least the next several months. That said, if you wanted to create a PR that addresses your concerns, I am sure we would review. The proper place though, is going to be in the tao or wry repositories, Tauri would then integrate such low level interfacing.

amrbashir commented 3 years ago

No additional functionality is needed in Tao, we already expose a method to get the gtk_window so users can do what they want with it, will transfer back to tauri.

amrbashir commented 3 years ago

Here is the relevant code in Tao https://www.github.com/tauri-apps/tao/tree/dev/src%2Fplatform%2Funix.rs#L18

LucaCoduriV commented 1 year ago

@reujab Hello, did you achieve to create a layer shell ?

LucaCoduriV commented 1 year ago

No additional functionality is needed in Tao, we already expose a method to get the gtk_window so users can do what they want with it, will transfer back to tauri.

It looks like it is impossible to make a layer shell because the gtk_window is already used before getting it with the getter.

JohnDoeAntler commented 1 year ago

No additional functionality is needed in Tao, we already expose a method to get the gtk_window so users can do what they want with it, will transfer back to tauri.

It looks like it is impossible to make a layer shell because the gtk_window is already used before getting it with the getter.

Agree, here is my attempt

// tauri = { version = "1.4", features = ["shell-open"] }
// serde = { version = "1.0", features = ["derive"] }
// serde_json = "1.0"
// gtk-layer-shell = "0.4.4"

// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use tauri::Manager;
use gtk_layer_shell::init_for_window;

fn main() {
    tauri::Builder::default()
      .setup(|app| {
        let main_window = app.app_handle().get_window("main").unwrap();
        let gtk_window = main_window.gtk_window().unwrap();

        init_for_window(&gtk_window);

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

the result looks just like what @LucaCoduriV said

** (tauri-app:1234859): CRITICAL **: 20:59:12.253: custom_shell_surface_init: assertion '!gtk_widget_get_mapped (GTK_WIDGET (gtk_window))' failed

https://github.com/wmww/gtk-layer-shell/blob/master/src/custom-shell-surface.c#L80

Since the initial goal was to enable Tauri to use layer shell, should this issue be marked as open again?

LucaCoduriV commented 1 year ago

To be able to make layer shell would be so nice ! It would open a lot of possibilities !

LucaCoduriV commented 8 months ago

@amrbashir @nothingismagick Can we reopen this issue ?

amrbashir commented 8 months ago

the expected API is already exposed here https://docs.rs/tauri/latest/tauri/window/struct.Window.html#method.gtk_window so there is no reason to re-open the issue.

FabianLars commented 8 months ago

Well, this part seems to be unresolved:

It looks like it is impossible to make a layer shell because the gtk_window is already used before getting it with the getter.

Though i'm not sure how to resolve it in tauri tbh. Maybe a setter in the WindowBuilder? Or maybe this is just something we consider out of scope for tauri itself and something that should be done by using Wry instead idk

amrbashir commented 8 months ago

This should have its own issue then

asqarslanov commented 1 month ago

Thanks to @MrAdhit’s comment (https://github.com/andrewbaxter/wongus/issues/4#issuecomment-2408108123), I managed to make Tauri work with GTK Layer Shell. I hope this will be useful to someone.

// [dependencies]
// gtk = "0.18.1"
// gtk-layer-shell = "0.8.1"

use gtk::prelude::{ContainerExt, GtkWindowExt, WidgetExt};
use gtk_layer_shell::LayerShell;
use tauri::Manager;

tauri::Builder::default()
    .setup(|app| {
        let main_window = app.get_webview_window("main").unwrap();
        main_window.hide().unwrap();

        let gtk_window = gtk::ApplicationWindow::new(
            &main_window.gtk_window().unwrap().application().unwrap(),
        );

        // To prevent the window from being black initially.
        gtk_window.set_app_paintable(true);

        let vbox = main_window.default_vbox().unwrap();
        main_window.gtk_window().unwrap().remove(&vbox);
        gtk_window.add(&vbox);

        // Doesn't throw errors.
        gtk_window.init_layer_shell();

        // Just works.
        gtk_window.set_layer(gtk_layer_shell::Layer::Top);

        gtk_window.set_width_request(640);
        gtk_window.set_height_request(480);

        gtk_window.show_all();
        Ok(())
    })
    .run(tauri::generate_context!())
    .unwrap();
TheCodedProf commented 1 month ago

Hey! I'm writing an app that requires a keyboard to use. To get keyboard focus I also had to add:

// gtk-layer-shell = { version = "0.8.1", features = ["v0_6"] }
gtk_window.set_keyboard_mode(gtk_layer_shell::KeyboardMode::Exclusive);

to allow for keyboard interactivity.

chiyuki0325 commented 1 week ago

Thanks for this solution! The above code can indeed create a webview window with layer shell enabled.

However, I cannot use app_handle.get_webview_window("main").hide() to hide the window on demand because get_webview_window still gets the original window that we have hidden instead of this new gtk_window.

I need a new solution... Thanks.