linebender / druid

A data-first Rust-native UI design toolkit.
https://linebender.org/druid/
Apache License 2.0
9.54k stars 569 forks source link

implement 'show titlebar' window option #634

Open cmyr opened 4 years ago

cmyr commented 4 years ago

This was implemented on gtk in #587. This is at least somewhat complicated on mac; it isn't 100% clear what it should correspond to. If there is no window border on mac that means the window also is not resizable or moveable by default. Is that the intended behaviour? this needs to be clarified.

cc @Psykopear: exactly what is the intended behaviour of a window that has show_titlebar false? can that window be resized or moved? We may need to slightly rethink this..

futurepaul commented 4 years ago

In electron a "frameless" window is non-draggable by default and it's up to the user to implement a draggable region: https://www.electronjs.org/docs/api/frameless-window

Electron also has more granular settings for mac, including hiding the title bar but showing the traffic light buttons.

futurepaul commented 4 years ago

Some Apple documentation here: here's how to hide the titlebar, but it warns that this only makes sense when NSFullSizeContentViewWindowMask is true. But NSFullSizeContentViewWindowMask is "deprecated." So... \o/

futurepaul commented 4 years ago

Some relevant discussion for winit

Psykopear commented 4 years ago

So, from a Linux perspective, I'd expect that setting show_titlebar as false starts the application with no border and no titlebar (equivalent to the decorated gtk option). Then it's up to the application to implement a draggable region, like futurepaul said for electron. And that's it, I think that other properties like the ability to resize and move the window should remain unchanged when setting show_titlebar.

The resizable should only give a fixed size to the window (on tiling window managers that support floating windows, the window might also implicitly become floating, but that's up to the WM I think).

Non movable windows also could be required (I'm thinking of applications like conky), and always as a separate setting. That could also imply the non resizable property, but not the other way around.

I don't know if those patterns makes sense on other OS, but at least on Linux they are used independently. Some examples could be:

My point is that having separate options for moveability, resizability and borderless drawing would be an expected pattern in Linux applications. Can't say anything about Mac, but for example bitwig works the same on Windows, so it could work similarly there.

Note: Keep in mind that I'm not experienced in GUI development in general, so what I'm saying comes from the point of view of a Linux user rather than an expert in Linux GUI development.

rhzk commented 4 years ago

Would also like a option for setting the position of the window (at least when its created)

Example for Windows to remove title bar and set a position:

if !self.show_titlebar {
    dwStyle = WS_POPUP // Removes title bar and borders
}

let hwnd = create_window(
    dwExStyle,
    class_name.as_ptr(),
    self.title.to_wide().as_ptr(),
    dwStyle,
    self.pos.width as i32, // Initial x position of the window (from top-left)
    self.pos.height as i32, // Initial y position of the window (from top-left)
    width,
    height,
    0 as HWND,
    hmenu,
    0 as HINSTANCE,
    win,
);

++ functionality to set self.pos But I don't know for Linux or Mac-OS

This could also allow to create GUI elements for moving/resizing the window

cmyr commented 4 years ago

yep, we should be able to position windows. For this to really be complete though we also need an API that lets us figure out how many displays are connected, and to identify them, and I'm not very excited about designing that API.

In any case this feels like a separate issue; feel free to open it if you'd like @rhzk?

ForLoveOfCats commented 4 years ago

Something to note is that Wayland under Linux does not allow setting or retrieving window positions last time I worked on something related to this a few years ago. A cursory googling shows that it appears to still be the case but I may be wrong.

rjwittams commented 4 years ago

@ForLoveOfCats Do you know how things like popup menus, tooltips and combo boxes work on wayland given this? Sounds like they must be internally painted which is a bit weird

ForLoveOfCats commented 4 years ago

My understanding is that Wayland applications are generally allowed to paint outside what would be normally considered their window bounds. Don't quote me on that though.

rjwittams commented 4 years ago

It looks like you can use these https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_subsurface subsurface things. You can position it relative to your window. But not sure how you can make sure it doesn't go off the edge of a monitor.

terhechte commented 3 years ago

@cmyr There would be two ways of implementing this on macOS; either by hiding the title bar, or by hiding the window chrome and the title. They result in slightly different results. Hiding window chrome and title results in a window which still has rounded corners as well as the close / minify / fullscreen buttons (screenshots from interface builder because I'm lazy, so ignore the frames around the window):

Screen Shot 2021-07-02 at 14 35 25 Screen Shot 2021-07-02 at 14 37 18

I'd happily implement either of these two, or maybe there's a way to make both of them available?

cmyr commented 3 years ago

@terhechte this definitely needs a cross-platform API design, but I do think we should make platform-specific details available behind an extension trait; see #1843 for a discussion of a similar issue.

From a higher level, I think using electron's API as a guideline isn't a bad place to start, in terms of figuring out what set of capabilities are reasonable to implement in a cross-platform way.