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

-webkit-app-region: drag eats all click events #1354

Closed
mafintosh opened this Issue Apr 4, 2015 · 17 comments

Comments

Projects
None yet
@mafintosh
Copy link
Contributor

mafintosh commented Apr 4, 2015

When setting -webkit-app-region: drag to make the window draggable all click/mousedown/mouseup can no longer be captured.

// assuming body { -webkit-app-region: drag; }
document.body.addEventListener('click' , function () {
  console.log('i am never triggered')
}, false)
@paulcbetts

This comment has been minimized.

Copy link
Contributor

paulcbetts commented Apr 4, 2015

You need to exclude the items you want clickable via -webkit-app-region: no-drag

@mafintosh

This comment has been minimized.

Copy link
Contributor Author

mafintosh commented Apr 4, 2015

There is no way to have both? My use-case is double-clicking a video and going to fullscreen but being able to drag the video to drag the app window (similar to how quicktime works)

@paulcbetts

This comment has been minimized.

Copy link
Contributor

paulcbetts commented Apr 4, 2015

You could just move the window manually when the user clicks it and moves the mouse

@zcbenz

This comment has been minimized.

Copy link
Member

zcbenz commented Apr 7, 2015

The -webkit-app-region: drag is a hint to operating system that the area is a draggable area like window's titlebar, and the operating system will hijack all mouse events of the area to make it behave like titlebar.

There is no way to work around it in both web apps and native apps, if you want to catch all events you have to move the window manually by recording how user drags and moves the mouse.

I'm closing this as won't fix.

@sapjax

This comment has been minimized.

Copy link

sapjax commented Aug 20, 2015

realy?
but nw.js works well

@MartinMa

This comment has been minimized.

Copy link
Contributor

MartinMa commented Sep 30, 2015

@sapjax Do you know how nw.js solves this? Do you have an example what works?

Properly speaking, the caption area of a window has more to it than just moving the window around. From a Windows perspective, a caption area is brought into being by looking at the cursor coordinates and returning HTCAPTION when handling a WM_NCHITTEST window message (which usually occurs in combination with a mouse event).

  • Moving of the window
  • Double-click maximizes the window (restores the window respectively).
  • Aero snap

Apart from Aero snap, everything can be emulated (more or less painfully).

💡
How about adding something like a non-client-hit-test event to BrowserWindow. That way the developer would be able to implement it's own logic to tell the operating system which part of the window is the caption area, client area, maximize button etc.

I don't know about OS X and Linux though ...

@MarshallOfSound

This comment has been minimized.

Copy link
Member

MarshallOfSound commented Feb 8, 2016

@zcbenz The fixing of -webkit-app-region: drag absorbing all click events being marked as wontfix is fair enough. But is there any way we could implement a way to trigger the dragging of a browser window without marking it as "draggable". I know on windows you can trigger a mousecapture and trick things into being dragged.

Shortest example I could find
http://stackoverflow.com/questions/1592876/make-a-borderless-form-movable

ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
@JemiloII

This comment has been minimized.

Copy link

JemiloII commented May 11, 2017

This is strange that this is a won't fix. I can have a draggable div and made elements on the div non-draggable. However having a floating div, for window controls, set to non draggable will stay draggable. Unless are people trying to do something different? I just want to understand.

@JemiloII

This comment has been minimized.

Copy link

JemiloII commented May 11, 2017

I figured out how to kinda get around it. It is all about the order you place the elements. So if element can-drag is in a fixed position and then you add a no-drag element that overlaps, even if its z-index is lower. You won't click.


However, this becomes magical when you reverse the order. Very magical! Because now you can click the element and it's contents. Though this option seems to only work with fixed/absolutes. I haven't bothered with dynamically placed elements yet.


Thought this would be helpful for anyone making some simple controls or overlays~

@Himujjal

This comment has been minimized.

Copy link

Himujjal commented Jan 15, 2018

@JemiloII I would like to know how you did it. Its an urgent project and please tell me the solution as fast as you can.

@ihachani

This comment has been minimized.

Copy link

ihachani commented Jan 19, 2018

@JemiloII Can you elaborate more on your workaround. I am facing a similar problem.

HyunmoAhn added a commit to AhKi/oh-my-desk that referenced this issue Mar 10, 2018

Fix web widget title bar style for click event
I found title bar button is not actived in window environment
Because Button's parenet has `-webkit-app-region: drag` style code.
So Add Button style that `-webkit-app-region: no-drag`.

ref electron/electron#1354

HyunmoAhn added a commit to AhKi/oh-my-desk that referenced this issue Mar 10, 2018

Fix web widget title bar style for click event
I found title bar button is not actived in window environment
Because Button's parenet has `-webkit-app-region: drag` style code.
So Add Button style that `-webkit-app-region: no-drag`.

ref electron/electron#1354
@phil294

This comment has been minimized.

Copy link

phil294 commented Apr 10, 2018

Unfortunately, it also eats up scroll events which is pretty horrible.

@nathansherburn

This comment has been minimized.

Copy link

nathansherburn commented May 4, 2018

I came up with a work around that may be useful for anyone coming here looking to prevent click events after dragging.

  1. Get the pointer position onmousedown and save it to a variable (you can use electron.screen.getPrimaryDisplay())
  2. Get the pointer position again onmouseup and check if it has changed.
  3. If it has changed, treat it as a drag event.
  4. If it has not changed, treat it as a click event.

Hopefully this helps someone!

@mhuggins mhuggins referenced this issue May 6, 2018

Merged

Fixed input focus not working on register screen #129

4 of 8 tasks complete
@JemiloII

This comment has been minimized.

Copy link

JemiloII commented May 11, 2018

When I meant by order of elements, I meant in the html code.

@danielravina

This comment has been minimized.

Copy link

danielravina commented Jul 12, 2018

I've been struggling with this problem for weeks. I found a great workaround that works flawlessly on all systems with requestAnimationFrame:

HTML:

<div id="draggable" onmousedown="onMouseDown"/>

Renderer Process:

let animationId;
let mouseX;
let mouseY;

function onMouseDown(e) {
  mouseX = e.clientX;  
  mouseY = e.clientY;

  document.addEventListener('mouseup', onMouseUp)
  requestAnimationFrame(this.moveWindow);
}

function onMouseUp(e) {
  window.ipcRenderer.send('windowMoved');
  document.removeEventListener('mouseup', onMouseUp)
  cancelAnimationFrame(animationId)
}

function moveWindow() {
  window.ipcHandler.send('windowMoving', { mouseX, mouseY });
  animationId = requestAnimationFrame(moveWindow);
}

Main Process:

ipcMain.on('windowMoving', (e, {mouseX, mouseY}) => {
  const { x, y } = electron.screen.getCursorScreenPoint()
  this.win.setPosition(x - mouseX, y - mouseY)
});

ipcMain.on('windowMoved', () => {
  // Do somehting when dragging stop
);

Hope this helps someone!

@Maeeen

This comment has been minimized.

Copy link

Maeeen commented Jul 23, 2018

@danielravina Your solution seems to be okay, but, remember that Windows has this "maximizing" feature, like, when you drag the title bar of a window to the top of your screen: it maximizes it automatically (also with sidebar where the window will take the half of the screen, and so on with the corner). And not only that, there's multiple "shortcuts" like that in multiple OS. If you use this technique, the user will lose all of theses features (which is kinda bad).

@jconnolly-bond

This comment has been minimized.

Copy link

jconnolly-bond commented Feb 25, 2019

Here is a workaround which is applicable if you're trying to get a click event from a non-document element which has -webkit-app-region: drag on it. You can add a mouse or click event to the document and then test for your desired element returned from the event.target.

document.addEventListener("mousedown", event => {
    if (event.target === targetElement) {
        // Logic
    }
}, false);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.