Git Product home page Git Product logo

tao's Introduction

TAO - Window Creation Library

License Chat Server website https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg support

Cross-platform application window creation library in Rust that supports all major platforms like Windows, macOS, Linux, iOS and Android. Built for you, maintained for Tauri.

Cargo Features

TAO provides the following features, which can be enabled in your Cargo.toml file:

  • serde: Enables serialization/deserialization of certain types with Serde.

Platform-specific notes

Android

This library makes use of the ndk-rs crates, refer to that repo for more documentation.

Running on an Android device needs a dynamic system library, add this to Cargo.toml:

[[example]]
name = "request_redraw_threaded"
crate-type = ["cdylib"]

And add this to the example file to add the native activity glue:

#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "on"))]
fn main() {
    ...
}

And run the application with cargo apk run --example request_redraw_threaded

Linux

Gtk and its related libraries are used to build the support of Linux. Be sure to install following packages before building:

Arch Linux / Manjaro:

sudo pacman -S gtk3

Debian / Ubuntu:

sudo apt install libgtk-3-dev

Acknowledgement

This is a fork of winit which replaces Linux's port to Gtk. In the future, we want to make these features more modular as separate crates. So we can switch back to winit and also benefit the whole community.

Partners

CrabNebula

For the complete list of sponsors please visit our website and Open Collective.

tao's People

Contributors

amrbashir avatar brendanzab avatar chrisduerr avatar elinorbgr avatar felixrabe avatar fkaa avatar francesca64 avatar frewsxcv avatar github-actions[bot] avatar goddessfreya avatar gw3583 avatar hecrj avatar jwilm avatar kchibisov avatar keiya01 avatar lemarier avatar lucasfernog avatar mitchmindtree avatar murarth avatar osspial avatar ozkriff avatar paulrouget avatar pedrocr avatar renovate[bot] avatar ryanisaacg avatar ryanstew avatar sodiumjoe avatar tomaka avatar vberger avatar wusyong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tao's Issues

Panel windows

I'd like to create a window/app that behaves like macOS Spotlight:

  1. It shows over fullscreen apps
  2. It doesn't deactivate the active app. If the window opens while you have Chrome focused, the Chrome menu bar is still shown and the Chrome window looks like it's still focused.

On macOS I think this kind of window is an NSPanel

macOS: Focus Can't be Obtained After Making Visible

Issue: Utilizing hotkeys to toggle a window's visibility & focus (in a tray app, for example) will not capture the application's focus.

Expected Behavior: A window should toggle to a visible state, and capture focus allowing it to be interacted with immediately (for things such as keyboard input, etc).

Minimum Reproduction: On MacOS 11.1 (20C69) Intel Core i5, the following code can be pasted into the examples/ and ran.

Minimum Reproducible Example
use tao::{
  accelerator::{Accelerator, SysMods},
  event::{Event, WindowEvent},
  event_loop::{ControlFlow, EventLoop},
  keyboard::KeyCode,
  platform::global_shortcut::ShortcutManager,
  window::WindowBuilder,
};

#[allow(clippy::single_match)]
fn main() {
  let event_loop = EventLoop::new();

  let window = WindowBuilder::new()
    .with_title("A fantastic window!")
    .with_inner_size(tao::dpi::LogicalSize::new(128.0, 128.0))
    .build(&event_loop)
    .unwrap();

  let shortcut_1 = Accelerator::new(SysMods::Shift, KeyCode::KeyB);
  let mut hotkey_manager = ShortcutManager::new(&event_loop);
  hotkey_manager.register(shortcut_1.clone()).unwrap();

  event_loop.run(move |event, _, control_flow| {
    *control_flow = ControlFlow::Wait;
    match event {
      Event::GlobalShortcutEvent(hotkey_id) if hotkey_id == shortcut_1.clone().id() => {
        if window.is_visible() {
          println!("Making invisible");
          window.set_visible(false);
        } else {
          println!("Making Visible and Focused");
          window.set_visible(true);
          window.set_focus();
        }
      }
      Event::WindowEvent {
        event: WindowEvent::CloseRequested,
        window_id,
        ..
      } if window_id == window.id() => *control_flow = ControlFlow::Exit,
      Event::MainEventsCleared => {
        window.request_redraw();
      }
      _ => (),
    }
  });
}

Alternatively, here's a short video:

Screen.Recording.2021-07-07.at.11.26.59.PM.mov

Potential Root Cause

  • Appears to be a race condition in the Global Dispatch functionality. set_focus handler on window will only execute if the window is considered visible, while the set_visible handler is submitting an async event. The async event does not appear to complete in time for the set_focus call, thus the set_focus never attempts to emit a focus event since the window is considered is_visible == NO
  • Removing the visibility check on set_focus can resolve the problem, but potentially introduces some other problem.
  • Attempting to change the exec_async to exec_sync on make_key_and_order_front_async triggered an Illegal Hardware Instruction on my machine; but I'm not that experienced with this system.

Implement ability to show text in the system tray/menu bar

Use case: apps like MeetingBar show text instead of a system tray icon.

image

I'd love the ability to do this with Tauri:

  • Show text instead of the system tray icon, and be able to update it during runtime.
  • Show text next to the system tray icon.

However, I'm not sure if this is even possible in other operating systems. With that in mind, maybe it doesn't fit Tauri's philosophy to add a feature that will only work on macos!

CPU 100% when running the hello world

Describe the bug
When running the hello world, the cpu usage is 100% on my ubuntu 20.10 machine

Steps To Reproduce
Just run the hello world example

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Platform and Versions (please complete the following information):
OS: Ubuntu 20.10
Rustc:1.52.1

Would you assign yourself to resolve this bug?

  • Yes
  • No

Additional context
I open this error as a follow up to the one I opened on the TAURI repo (tauri-apps/tauri#1813), as the error seems to stem from the wry part, as shown by running the hello wolrd example, as advised to me on the Discord help triage.

feat: Better `set_focus` handling

Right now on macOS we had to disable the is_visible check as it's async.
On Windows and Linux it works fine.

Maybe we should do a cleanup in this.

You can test with this examples;

use simple_logger::SimpleLogger;
use tao::{
  accelerator::{Accelerator, SysMods},
  event::{Event, WindowEvent},
  event_loop::{ControlFlow, EventLoop},
  keyboard::KeyCode,
  platform::global_shortcut::ShortcutManager,
  window::WindowBuilder,
};

#[allow(clippy::single_match)]
fn main() {
  let event_loop = EventLoop::new();

  let window = WindowBuilder::new()
    .with_title("A fantastic window!")
    .with_inner_size(tao::dpi::LogicalSize::new(128.0, 128.0))
    .build(&event_loop)
    .unwrap();

  let shortcut_1 = Accelerator::new(SysMods::Shift, KeyCode::KeyB);
  let mut hotkey_manager = ShortcutManager::new(&event_loop);
  hotkey_manager.register(shortcut_1.clone()).unwrap();

  event_loop.run(move |event, _, control_flow| {
    *control_flow = ControlFlow::Wait;
    match event {
      Event::GlobalShortcutEvent(hotkey_id) if hotkey_id == shortcut_1.clone().id() => {
        if window.is_visible() {
          println!("Making invisible");
          window.set_visible(false);
        } else {
          println!("Making Visible and Focused");
          window.set_visible(true);
          window.set_focus();
        }
      }
      Event::WindowEvent {
        event: WindowEvent::CloseRequested,
        window_id,
        ..
      } if window_id == window.id() => *control_flow = ControlFlow::Exit,
      Event::MainEventsCleared => {
        window.request_redraw();
      }
      _ => (),
    }
  });
}

Update `tray` menu items

We should have the option to rebuild the tray menu after the app is launched.

  • Windows
  • macOS
  • Linux

How to emit event into frontend with menu items ?

Problem

As far as the docs and the source code says I'm not able to communicate between backend and frontend via menu actions, which is very crucial yet unmentioned.

tauri::Builder::default()
   ....

For example .on_system_tray_event(handler) the handler accepts the app, event parameters but not in .on_menu_event(handler) which causes my problem.

[Regression] Segfault when running two instances

Describe the bug
Running wry twice it segfaults

Steps To Reproduce
cargo run --example hello_world & cargo run --example hello_world

Expected behavior
Two instances should start

LOG

(process:246998): Gtk-CRITICAL **: 09:57:30.630: _gtk_style_provider_private_get_settings: assertion 'GTK_IS_STYLE_PROVIDER_PRIVATE (provider)' failed

(process:246998): Gtk-CRITICAL **: 09:57:30.632: _gtk_style_provider_private_get_settings: assertion 'GTK_IS_STYLE_PROVIDER_PRIVATE (provider)' failed

(process:246998): Gtk-CRITICAL **: 09:57:30.632: _gtk_style_provider_private_get_settings: assertion 'GTK_IS_STYLE_PROVIDER_PRIVATE (provider)' failed
Wry has started!
[1]  + 246998 segmentation fault (core dumped)  cargo run --example hello_world

Platform and Versions (please complete the following information):
OS: Linux
Rustc: 1.53.0-nightly (42816d61e 2021-04-24) also on stable

Would you assign yourself to resolve this bug?

  • Yes
  • No

Additional context
This is a regressing, 0.8.0 works fine

feat: `with_has_shadow`, `has_shadow` and `set_has_shadow`

Is your feature request related to a problem? Please describe.
When using decorations: false the app removes not only the topbar & border, but also the shadow.

Describe the solution you'd like
I would like to see the shadow separated into it's own config property. So you could e.g. do:

"windows": [
  {
    "shadow": true,
    "decorations": false
  }
]

Which would result in a window without the top bar, without borders but with the OS shadow.

Describe alternatives you've considered
I tried building this in my app, but this comes with a lot of edge cases. You can't click through the shadow, you have to dynamically change the spacing/shadow when you are full screen, etc.

Additional context
This was experienced on Windows, I have not tested behavior on other OS'.

Calling "open file" dialog throws panick

Describe the bug
calling await open({ multiple: false }) (imported from import { open } from "@tauri-apps/api/dialog";) ends up in panick, after seeing the dialog box in a flash:

(app:302337): Gtk-WARNING **: 13:34:48.975: Theme directory 32@2x/devices of theme Vimix-dark has no size field

thread 'main' panicked at 'already borrowed: BorrowMutError', /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tao-0.2.5/src/platform_impl/linux/event_loop.rs:598:20
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

With backtrace :

(app:303799): Gtk-WARNING **: 13:41:16.119: Theme directory 32@2x/devices of theme Vimix-dark has no size field

thread 'main' panicked at 'already borrowed: BorrowMutError', /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tao-0.2.5/src/platform_impl/linux/event_loop.rs:598:20
stack backtrace:
   0: rust_begin_unwind
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/panicking.rs:92:14
   2: core::option::expect_none_failed
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/option.rs:1329:5
   3: core::result::Result<T,E>::expect
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/result.rs:997:23
   4: core::cell::RefCell<T>::borrow_mut
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/cell.rs:872:9
   5: tao::platform_impl::platform::event_loop::EventLoop<T>::run_return::{{closure}}
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tao-0.2.5/src/platform_impl/linux/event_loop.rs:598:7
   6: glib::main_context_channel::dispatch
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.10.3/src/main_context_channel.rs:244:20
   7: g_main_context_dispatch
   8: <unknown>
   9: g_main_loop_run
  10: gtk_native_dialog_run
  11: rfd::backend::gtk3::file_dialog::dialog_ffi::GtkFileDialog::run
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/rfd-0.3.0/src/backend/gtk3/file_dialog/dialog_ffi.rs:142:18
  12: rfd::backend::gtk3::file_dialog::<impl rfd::backend::FilePickerDialogImpl for rfd::dialog::FileDialog>::pick_file::{{closure}}
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/rfd-0.3.0/src/backend/gtk3/file_dialog.rs:27:16
  13: rfd::backend::gtk3::utils::GtkGlobalMutex::run_locked
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/rfd-0.3.0/src/backend/gtk3/utils.rs:25:9
  14: rfd::backend::gtk3::file_dialog::<impl rfd::backend::FilePickerDialogImpl for rfd::dialog::FileDialog>::pick_file
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/rfd-0.3.0/src/backend/gtk3/file_dialog.rs:20:9
  15: rfd::dialog::FileDialog::pick_file
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/rfd-0.3.0/src/dialog.rs:88:9
  16: tauri::api::dialog::FileDialogBuilder::pick_file
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tauri-1.0.0-beta.1/src/api/dialog.rs:41:5
  17: tauri::endpoints::dialog::open
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tauri-1.0.0-beta.1/src/endpoints/dialog.rs:161:5
  18: tauri::endpoints::dialog::Cmd::run
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tauri-1.0.0-beta.1/src/endpoints/dialog.rs:74:39
  19: tauri::endpoints::Module::run::{{closure}}::{{closure}}
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tauri-1.0.0-beta.1/src/endpoints.rs:117:38
  20: tauri::hooks::InvokeResolver<P>::return_closure
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tauri-1.0.0-beta.1/src/hooks.rs:209:33
  21: tauri::hooks::InvokeResolver<P>::respond_closure
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tauri-1.0.0-beta.1/src/hooks.rs:162:5
  22: tauri::endpoints::Module::run::{{closure}}
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tauri-1.0.0-beta.1/src/endpoints.rs:116:11
  23: core::ops::function::FnOnce::call_once{{vtable.shim}}
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/ops/function.rs:227:5
  24: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/alloc/src/boxed.rs:1546:9
  25: <tauri_runtime_wry::Wry as tauri_runtime::Runtime>::run::{{closure}}
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tauri-runtime-wry-0.1.1/src/lib.rs:892:9
  26: tao::platform_impl::platform::event_loop::EventLoop<T>::run_return
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tao-0.2.5/src/platform_impl/linux/event_loop.rs:609:11
  27: tao::platform_impl::platform::event_loop::EventLoop<T>::run
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tao-0.2.5/src/platform_impl/linux/event_loop.rs:117:5
  28: tao::event_loop::EventLoop<T>::run
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tao-0.2.5/src/event_loop.rs:150:5
  29: <tauri_runtime_wry::Wry as tauri_runtime::Runtime>::run
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tauri-runtime-wry-0.1.1/src/lib.rs:882:5
  30: tauri::app::Builder<E,L,MID,TID,A,R>::run
             at /home/olup/.cargo/registry/src/github.com-1ecc6299db9ec823/tauri-1.0.0-beta.1/src/app.rs:588:5
  31: app::main
             at ./src/main.rs:7:3
  32: core::ops::function::FnOnce::call_once
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

This use to work before today tao + wry updates

To Reproduce
Steps to reproduce the behavior:

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Platform and Versions (please complete the following information):
Operating System - Ubuntu, version 20.10 X64

Node.js environment
Node.js - 14.15.5
@tauri-apps/cli - 1.0.0-beta.1
@tauri-apps/api - 1.0.0-beta.1

Global packages
npm - 6.14.11
yarn - 1.22.10

Rust environment
rustc - 1.52.1
cargo - 1.52.0

App directory structure
/public
/build
/node_modules
/.git
/src
/src-tauri

App
tauri.rs - 1.0.0-beta.1
build-type - bundle
CSP - default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'
distDir - ../build
devPath - http://localhost:4000
framework - React

Additional context
Add any other context about the problem here.

Stack Trace

What is valid for key Space as accelerator name?

System: macOS Big Sur 11.4

Code/Problem

CustomMenuItem::new("start_stop".to_string(), "Start/Stop").accelerator("Space");

Giving name Space won't work also tried, "space", " ", "_"

Output

no key equivalent for Accelerator { id: Some(AcceleratorId(39259)), mods: (empty), key: Space }

feat: `app.hide()` and `app.show()`

Would be nice to have the ability to hide the app, so that the app loses focus, just like the MyApp > Hide MyApp menu item. Mostly useful for macOS

Implement ability to change the system tray icon during runtime

Many apps (for an easy example: Slack) change their system tray icon depending on app state.

I believe it's not possible to do this in Tauri, because systsem tray icons are defined statically in tauri.conf.json. It would be nice to be able to change the icon in the app runtime.

Set `CRATE_TOKEN` in Github secrets

  • License headers
  • Authors field and package meta
  • Align Readme with tauri (description) and badges
  • Library description (github)
  • Library documentation quick review
  • Delete existing tags on current repo to prevent any issues

feat: add `window.set_visible_on_all_workspaces()`

As discussed here.

It would be great to have the ability to have some sort of API, possibly window.set_visible_on_all_workspaces() to allow apps made with tao the ability to be shown on all spaces, regardless of what space they were created on.

I have achieved this in a local copy of tao by adding the following in src/platform_impl/macos/window.rs line 195.

      ns_window.setCollectionBehavior_(NSWindowCollectionBehavior::NSWindowCollectionBehaviorCanJoinAllSpaces);
      ns_window.setCollectionBehavior_(NSWindowCollectionBehavior::NSWindowCollectionBehaviorMoveToActiveSpace);
       // TODO: get a real level?
      ns_window.setLevel_(10000);

I hope that helps. Please let me know if you need a hand implementing or testing.

refactor(unix): update gtk3 to gtk4

We now use more updated version of gtk3 and it depreciates lots of functions.
Some of them are unable to remove because gtk3 simply doesn't offer alternatives.
And since there's a new crate for gtk4 lately. We probably should try to migrate to it.

bug: incorrect monitor size on linux

from @FabianLars on discord:

i also started looking into the center thingy and it looks like the root cause is an incorrectly reported monitor size (470,300 instead of 1440p on my end), which causes a attempt to subtract with overflow error. Unfortunately i have to start cooking now sweat_smile

deps(gtk): bump to 0.14

Reminder to update to gtk-rs latest version

Seems to have conflict with sourceview

The repo is archived not sure if they'll release a new version.....

feat: add `minimizable` and `maximizable` options

Feature required where when alwaysOnTop is set to true, then even clicking on the app icon on the OS's task bar should not minimize the application and it stays always on top unless exited by the user.
Thanks,
Donnie

Hotkey is registered but not triggered on press

in src-tauri/src/main.rs I added these lines

Code

fn main() {
  tauri::Builder::default()
    .setup(|_app| {
      let h: Hotkey = Hotkey {
        keys: vec![Key::SPACE],
        modifiers: vec![Modifier::SHIFT],
      };
      let mut hm = HotkeyManager::new();
      match hm.register(h.clone(), || println!("hotkey pressed")) {
        Ok(_) => {
          println!("OK, {:?}", hm.is_registered(&h));
          Ok(())
        }
        Err(e) => panic!("{:?}", e),
      }
    })
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

Output

    Finished dev [unoptimized + debuginfo] target(s) in 4.73s
     Running `target/debug/app`

OK, true <~ the one I printed

It does print true for is_registered but still not triggering on tauri app or anywhere else.

Ability to get mouse position while dragging files onto Tauri window

Is your feature request related to a problem? Please describe.
The problem is inherited from winit. In short:
Winit doesn't send any CursorMoved events (nor CursorEntered) before DroppedFile, only immediately after. That's too late, if you want to know the mouse position before DroppedFile is received, e.g. if your app has different drop areas, and you need to know onto which one the files are dropped!

Describe the solution you'd like
Tao should send CursorEntered event as soon as the file-dragging cursor moves over the Tao window, and continuously send CursorMoved events as the cursor moves.

Describe alternatives you've considered
In my imgui-rs based frontend I worked around this by delaying all DroppedFile events until the first CursorMoved event is received, so that at the time of processing DroppedFile, imgui has already received the latest mouse pos. (On Win 8.1, CursorMoved always seems to come 2 frames after DroppedFile.)

// This event processor delays DroppedFile events until the first CursorMoved event is received,
// so that at the time of processing DroppedFile, imgui has the correct mouse pos.
// (On Win 8.1, CursorMoved always seems to come 2 frames after DroppedFile.)
/*
unfixed:
frame 446, DroppedFile: foo.txt
frame 448, CursorMoved: (377.0, 79.0)
desired:
frame 448, CursorMoved: (377.0, 79.0)
frame 448, DroppedFile: foo.txt
*/
#[derive(Default)]
pub struct CursorMovedB4DroppedFile<'a> {
	event_queue: Vec<Event<'a, ()>>,
	waiting_for_cursor_moved_event: bool,
}

impl<'a> CursorMovedB4DroppedFile<'a> {
	// each frame, call push before poll
	fn push(&mut self, ev: Event<'a, ()>) {
		// TODO: respect event's window_id ?
		let move_dropped_file_events_to_end_of_queue = match &ev {
			Event::WindowEvent { event: WindowEvent::DroppedFile(_path), .. } => {
				self.waiting_for_cursor_moved_event = true;
				false
			}
			Event::WindowEvent { event: WindowEvent::CursorMoved { .. }, .. } => {
				self.waiting_for_cursor_moved_event = false;
				true
			}
			_ => false,
		};
		self.event_queue.push(ev);
		if move_dropped_file_events_to_end_of_queue {
			self.event_queue.sort_by_key(|ev| {
				matches!(ev, Event::WindowEvent { event: WindowEvent::DroppedFile(_), .. })
			});
		}
	}

	fn poll(&mut self) -> impl Iterator<Item = Event<'a, ()>> + '_ {
		let waiting_for_cursor_moved_event = self.waiting_for_cursor_moved_event;
		self.event_queue.drain_filter(move |ev| match ev {
			Event::WindowEvent { event: WindowEvent::DroppedFile(_path), .. } => {
				!waiting_for_cursor_moved_event
			}
			_ => true,
		})
	}

	pub fn push_and_poll(&mut self, ev: Event<'a, ()>) -> impl Iterator<Item = Event<'a, ()>> + '_ {
		self.push(ev);
		self.poll()
	}
}

Note that I cannot use this workaround with Tauri because it doesn't let me process the events coming from Tao.

Additional context
Note: My workaround is not a satisfying solution, because in my frontend, while the user is dragging files and hovering the mouse, I would like to highlight the currently hovered drop area, which is not possible with this workaround because I only receive the CursorMoved event in the same frame as the DroppedFile event(s). But I'd still advocate for including this workaround in Tao if the full fix is infeasible for now, because it's better than having the wrong mouse pos at the time of drop, so that the user is left wondering why the drop area hasn't received the file.
(Currently Tao/winit thinks the mouse pos at the time of receiving DroppedFile is still where it was before the cursor last left the window, which is a totally confusing behavior for the user.)

[Feature] Hidden Window menu, triggered by shortcut

When using Firefox you can display the window menu (file edit etc) by pressing alt.
It could be a nice feature to have that, maybe even with a custom shortcut instead of just alt, for the custom menu items as well

Add more variants or options to SystemTrayMenuItem

This requires some API design, but I'm missing some functionality in the tray items:

  • A menu item that's not clickable but contains text.
  • Alternatively, an option for the Custom menu item that makes it not clickable. The options could be extended to accept different styles somehow?

This all sounds hard to make cross-platform.

Tracking issue of tao interface for Gtk

We are going to have a new unified interface to build window after tauri-apps/wry#163. It should cover most usage in Tauri.
But there are still many missing features for gtk. Below is the list of features (but not limited to):

  • window methods (see comment below)
  • events (see comment below)
  • platform traits (need to discuss what traits and methods are needed)
  • monitor module
    • MonitorHandle
    • VideoMode

feat: Add always below other windows

reason1: for completeness
use case: since it is possible to make the window transparent and not show borders/decorations i thought it would be nice to make a new multiplatform conky alternative which would be nicer to configure since its all html/css. As far as i can see, this is the only feature really missing for this.

EventLoop creation can fail on Linux.

EventLoop::new can, and will, fail on Linux when the display server isn't active. This is most easily reproduced via switching to a different TTY and trying to run a Tao app. While this does seem a bit out of scope (trying to run a GUI app on a system without a UI running), having a way to handle this would be optimal.

As of right now, window creation does return a result. On that same path, having event loop creation return a result seems feasible, yet would mean an API break. Alternatively, a new function to check if the GUI is accessible could work.

With GTK specifically, gtk_init_check exists and will return a GBoolean of false if the display server couldn't be connected to. That said, Tao uses the Application API instead of gtk_init. It is possible to run gtk_init multiple times though, so having one call to gtk_init_check before a call to the Application API could work.

Locally, while working with Wry, I was able to implement this via

use gtk;
fn new_webview() -> wry::Result<CustomWebViewDataType> {
  //Make sure WebView is available.
  webview::webview_version()?;
  match gtk::init() {
    Err(e) => Err(wry::Error::GlibBoolError(e)),
    Ok(_) => {
      let event_loop: EventLoop<()> = EventLoop::new();
      ...

That said, this is suboptimal for multiple reasons. My main comment is that Tao is in the perfect position to handle this. I had to look at the GTK version being used, specify it myself, and directly call it, when the expectation is on Tao to manage GTK (and other backends which may have similar quirks). There's also an expectation on EventLoop::new to never error, given it's lack of a Result return type, when it easily can error (my cited cases were VPSs, people who have Xorg yet don't always run it, and people who use TTYs instead of terminal emulators).

In conclusion, modifying EventLoop::new to return a Result, or adding another function to check if a GUI is accessible in a way that allows the app to handle the case where it's not, would be greatly appreciated. While work arounds exist, and this is a bit niche, Tao is in the perfect position to handle this and should as a multi platform window manager.

Emit an error on invalid `globalShortcut` registration.

Problem Description

Currently, registering a key that contains an invalid key works. However, this should return an error.
For example:

globalShortcut.register("Control+Windows+J");

The above works, even though Windows is not a recognized key, and in fact, they hotkey is registered as if only Control+J was registered.

Expected behavior

globalShortcut.register("Control+Windows+J"); // Error

Feature Request: Constrain window width, but not window height.

See discussion including screenshots at Discord.

https://discord.com/channels/616186924390023171/625037620996734986/866688857139314729

"setting maxWidth breaks the vertical resizing" ... "also enforces the minHeight as its maxHeight"

My project need to be able to keep approximately the same width, but adjust height during runtime. E.g. like Apple Music for macOS does. It can be resized horizontally, but only up to a maxWidth. However height can be as high as you'd like.

macOS: Dock management

Ability to hide app from Dock

There's a window-level .skip_taskbar() method, but as far as I can tell nothing for hiding the app itself from the Dock

Custom menu bar

Hey!

Feature request, a custom menu bar, ie, remove the windows default buttons and move it around with a custom system. Would be very cool!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.