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

Add drag-resizing with cursor feature #2003

Closed
wants to merge 8 commits into from

Conversation

MrGibus
Copy link

@MrGibus MrGibus commented Aug 21, 2021

  • Tested on all platforms changed
  • Compilation warnings were addressed
  • cargo fmt has been run on this branch
  • cargo doc builds successfully
  • Added an entry to CHANGELOG.md if knowledge of this change could be valuable to users
  • Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior
  • Created or updated an example program if it would help users understand this functionality
  • Updated feature matrix, if new features were added or implemented

Fix for #725 on windows
Similar in scope to #1840

This has only been implemented for windows:
This comment offer insight as to how this would translate to Linux platforms.

As far as using this to make a borderless window in similar fashion to electron, the approach has several drawbacks:

  • No window resizing from win-hotkeys
  • No shadows on the borders

To solve those issues this SO Question and this windows dev tutorial seem to be the standard. I don't understand how this would fit into winit at this time however.

I briefly experimented with removing the title bar and not the border through winapi, which also seems to mostly solve the issues above and this may be preferable to hiding all decorations and implementing standard window functionality manually.

Copy link
Member

@maroider maroider left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a bunch for taking the time to implement this :D

I'd like to see an addition to the feature matrix for this feature.

As far as using this to make a borderless window in similar fashion to electron, the approach has several drawbacks:

* No window resizing from win-hotkeys

* No shadows on the borders

Indeed. But that's something that has to be solved in some other PR(s).
In fact, the first problem is being solved in #1891, although progress has unfortunately stalled a bit.

Comment on lines +200 to +206
style |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; // Note WS_BORDER IS INCLUDED IN WS_CAPTION
style_ex |= WS_EX_WINDOWEDGE;

// Nest inside Decorations to preserve borderless windows
if self.contains(WindowFlags::RESIZABLE) {
style |= WS_SIZEBOX | WS_MAXIMIZEBOX;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes will inevitably be overridden by #1891.
I ran a test where I merged #1891 into this PR (keeping only the changes from #1891), and it seemed to work just fine.
In light of this, it might make sense to wait until #1891 is merged and then rebase this PR onto master, although that assumes that we find a solution to the bugs blocking #1891 soon-ish.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main thing here is that the resizable bit is set to 1,

I had a brief look at #1891 and I think that by removing const NO_DECORATIONS_AND_MASK = !WindowFlags::RESIZABLE.bits; It's correcting the issue whereby resizeable is linked to the decorations. Which is the reason for my changes.

Besides that the only other point of note is that WS_BORDER isn't required where WS_CAPTION is set as The MS Docs state it's included. And similarly the WS_SYSMENU is only available with WS_CAPTION. This refactoring I did shouldn't be needed for this functionality, but may lead to weird issues further down the road.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#2419 has been merged and this PR should be unblocked now.

@MrGibus
Copy link
Author

MrGibus commented Sep 1, 2021

A few other PRs are failing the nightly wasm32 target build check.
usage of `--profile` requires `-Z unstable-options`
looks like a workflow bug?

@acid1103
Copy link

Hi all. It's been several months since this issue was last touched. I'm curious if this is something that's still being considered. I'm working on an app and recently added a custom (hacky) implementation of this feature for it, but something officially supported out-of-the-box would be great.

@MrGibus
Copy link
Author

MrGibus commented Mar 2, 2022

@acid1103 I ended up making my own borderless window proof of concept by using the windows API directly as the way winnit deals with the messaging system in the api doesn't lend itself well to rebuilding the decorations.

@MrGibus
Copy link
Author

MrGibus commented Oct 29, 2022

I think the best way of doing borderless windows on windows is to use the following on a WM_CREATE event:
(Using windows-rs)

/// with shadows
const BORDERLESS_MARGINS: MARGINS = MARGINS {
    cxLeftWidth: 1,
    cxRightWidth: 1,
    cyTopHeight: 1,
    cyBottomHeight: 1,
};

/// no shadows
const FLAT_MARGINS: MARGINS = MARGINS {
    cxLeftWidth: 0,
    cxRightWidth: 0,
    cyTopHeight: 0,
    cyBottomHeight: 0,
};

/// Primarily used to create borderless windows
/// https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Graphics/Dwm/fn.DwmExtendFrameIntoClientArea.html
/// https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmextendframeintoclientarea
pub fn extend_frame_into_client_area(handle: HWND, style: &WindowStyle) -> Result<()> {
    let margins = match style {
        WindowStyle::FlatBorderless => FLAT_MARGINS,
        WindowStyle::Borderless => BORDERLESS_MARGINS,
    };

    if handle.is_invalid() {
        panic!("Cannot extend frame into client area due to invalid window handle")
    }

    unsafe { DwmExtendFrameIntoClientArea(handle, &margins) }
}

See below example using wgpu to render over borders:
https://github.com/MrGibus/windows_borderless_rust

@amrbashir
Copy link
Contributor

Btw, this PR is superseded by #2515 and #2966

@daxpedda
Copy link
Member

Thanks @amrbashir!

@daxpedda daxpedda closed this Nov 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

6 participants