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

WebView is not visible on Android NDK - Godot #1475

Open
ShimixD opened this issue Jan 30, 2025 · 0 comments
Open

WebView is not visible on Android NDK - Godot #1475

ShimixD opened this issue Jan 30, 2025 · 0 comments

Comments

@ShimixD
Copy link

ShimixD commented Jan 30, 2025

Describe the bug
I was making a godot extension that creates a WebViewBuilder in Android, but when testing it it is not visible, I have done a debug and it seems to be created correctly.

use std::ptr::NonNull;
use std::ffi::{c_void};
use godot::prelude::*;
use godot::classes::{display_server::HandleType, Control, IControl, DisplayServer};
use wry::{WebViewBuilder, Rect};
use wry::dpi::{PhysicalPosition, PhysicalSize};
use raw_window_handle::{AndroidNdkWindowHandle, RawWindowHandle, WindowHandle};

struct GodotWRY;

#[gdextension]
unsafe impl ExtensionLibrary for GodotWRY {}

#[derive(GodotClass)]
#[class(base=Control)]
struct WebView {
    base: Base<Control>,
    webview: Option<wry::WebView>,
    #[export]
    full_window_size: bool,
    #[export]
    url: GString,
    #[export]
    html: GString,
    #[export]
    transparent: bool,
    #[export]
    background_color: Color,
    #[export]
    devtools: bool,
    #[export]
    headers: Dictionary,
    #[export]
    user_agent: GString,
    #[export]
    zoom_hotkeys: bool,
    #[export]
    clipboard: bool,
    #[export]
    incognito: bool,
    #[export]
    focused: bool,
}

#[godot_api]
impl IControl for WebView {
    fn init(base: Base<Control>) -> Self {
        Self {
            base,
            webview: None,
            full_window_size: true,
            url: "https://github.com/doceazedo/godot_wry".into(),
            html: "".into(),
            transparent: false,
            background_color: Color::from_rgb(1.0, 1.0, 1.0),
            devtools: true,
            headers: Dictionary::new(),
            user_agent: "".into(),
            zoom_hotkeys: false,
            clipboard: true,
            incognito: false,
            focused: true,
        }
    }

    fn ready(&mut self) {
        godot_print!("Initializing WebView...");
        
        let display_server = DisplayServer::singleton();
        godot_print!("DisplayServer obtained: {:?}", display_server);
        
        let window_handle = display_server.window_get_native_handle(HandleType::WINDOW_HANDLE);
        godot_print!("Window handle obtained: {:?}", window_handle);
        
        if window_handle == 0 {
            godot_error!("Error: Window handle is null.");
            return;
        }
        
        let android_handle = AndroidNdkWindowHandle::new(NonNull::new(window_handle as *mut c_void).unwrap());
        let raw_window_handle = RawWindowHandle::AndroidNdk(android_handle);
        godot_print!("RawWindowHandle created: {:?}", raw_window_handle);
    
        let window_handle = unsafe { WindowHandle::borrow_raw(raw_window_handle) };
        godot_print!("WindowHandle borrowed: {:?}", window_handle);
    
        if self.url.is_empty() && self.html.is_empty() {
            godot_error!("Error: Neither a URL nor HTML has been specified for the WebView.");
            return;
        }
    
        if !self.url.is_empty() && !self.html.is_empty() {
            godot_error!("Error: Both a URL and HTML code were provided. Only one can be used at a time.");
            return;
        }
    
        godot_print!("Creating WebView with URL: {}", self.url);
        let webview_builder = WebViewBuilder::new()
            .with_url(&self.url)
            .with_devtools(self.devtools);
    
        let webview = match webview_builder.build(&window_handle) {
            Ok(wv) => {
                godot_print!("WebView built successfully.");
                wv
            },
            Err(e) => {
                godot_error!("Error: Failed to build WebView: {:?}", e);
                return;
            }
        };
    
        self.webview.replace(webview);
    
        godot_print!("Getting root of SceneTree...");
        let mut viewport = match self.base().get_tree() {
            Some(tree) => match tree.get_root() {
                Some(root) => root,
                None => {
                    godot_error!("Error: Could not get root from the scene tree.");
                    return;
                }
            },
            None => {
                godot_error!("Error: Could not get SceneTree.");
                return;
            }
        };
        godot_print!("Root of SceneTree obtained: {:?}", viewport);
    
        godot_print!("Connecting size_changed signal...");
        viewport.connect("size_changed", &Callable::from_object_method(&*self.base(), "resize"));
        
        godot_print!("WebView test loaded");
        self.resize();
    }
}

#[godot_api]
impl WebView {
    #[func]
    fn resize(&self) {
        if let Some(webview) = &self.webview {
            let rect = if self.full_window_size {
                let viewport_size = self.base().get_tree().expect("Could not get tree").get_root().expect("Could not get viewport").get_size();
                Rect {
                    position: PhysicalPosition::new(0, 0).into(),
                    size: PhysicalSize::new(viewport_size.x, viewport_size.y).into(),
                }
            } else {
                let rect = self.base().get_global_rect();
                Rect {
                    position: PhysicalPosition::new(rect.position.x, rect.position.y).into(),
                    size: PhysicalSize::new(rect.size.x, rect.size.y).into(),
                }
            };
            let _ = webview.set_bounds(rect);
        }
    }
}

Steps To Reproduce
Create a GDExtension that returns the window view pointer.

Expected behavior
The webview must be visible on Android

Screenshots

Debug

Image

In game

Image

Platform and Versions (please complete the following information):
OS: Android ARM64
Rustc: 1.84.0 (9fc6b4312 2025-01-07)

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

No branches or pull requests

1 participant