'Electron Context menu on dragable area

Context menu On some platforms, the draggable area will be treated as a non-client frame, so when you right click on it a system menu will pop up. To make the context menu behave correctly on all platforms you should never use a custom context menu on draggable areas.

Taken from https://github.com/electron/electron/blob/master/docs/api/frameless-window.md

Is there a way to work around this. I need to have an image dragable and able to handle both click and right click events. (Much like Facebook messenger on mobile devices).

It setting an element as dragable (-webkit-app-region: drag;) and using context menu event works as expected in mac but when using the build on windows it doesn't work.



Solution 1:[1]

There is no way to have -webkit-app-region: drag; and a context menu on Windows. That's because Windows displays its own context menu for these UI items.

enter image description here

Another option is electron-drag which can simulate webkit-app-region.

Solution 2:[2]

do some as below, use pointerevent to capture mouse outside of BrowserWindow

diff --git a/src/main/boot.coffee b/src/main/boot.coffee
index 4a42164..18242f8 100644
--- a/src/main/boot.coffee
+++ b/src/main/boot.coffee
@@ -69,7 +69,7 @@ do =>
     if v instanceof Function
       #if not isPackaged
       ipcMain.handle k.join('.'), (e,args)=>
-        v(...args)
+        v.apply(e,args)

     for [name,func] from Object.entries v
       _handle [...k, name], func
diff --git a/src/main/ipc.coffee b/src/main/ipc.coffee
index d912ee2..6084543 100644
--- a/src/main/ipc.coffee
+++ b/src/main/ipc.coffee
@@ -10,6 +10,7 @@ export {default as count_down} from './ipc/count_down.coffee'
 `export * as recbar from './ipc/recbar.coffee'`
 `export * as USER from './ipc/user.coffee'`
 `export * as camera from './ipc/camera.coffee'`
+`export * as drag from './ipc/drag.coffee'`

 export {default as area} from './ipc/area.coffee'
 export {default as main} from './ipc/main.coffee'
diff --git a/src/main/ipc/drag.coffee b/src/main/ipc/drag.coffee
new file mode 100644
index 0000000..6edd12d
--- /dev/null
+++ b/src/main/ipc/drag.coffee
@@ -0,0 +1,12 @@
+#!/usr/bin/env coffee
+
+export setBounds = (x,y,width,height)->
+  win = @sender.getOwnerBrowserWindow()
+  # not use setPosition because https://github.com/electron/electron/issues/9477 browserWindow.setPosition(x,y) changed window size (windows/linux) with non default scaleLevel (125% for example)
+  win.setBounds {
+    x:Math.round(x)
+    y:Math.round(y)
+    width
+    height
+  }
+  return
diff --git a/src/web/src/lib/_on.coffee b/src/web/src/lib/_on.coffee
new file mode 100644
index 0000000..31d8beb
--- /dev/null
+++ b/src/web/src/lib/_on.coffee
@@ -0,0 +1,6 @@
+export default (elem, dict)=>
+  for event,func of dict
+    elem.addEventListener(event, func)
+  =>
+    for event,func of dict
+      elem.removeEventListener(event, func)
diff --git a/src/web/src/lib/drag.coffee b/src/web/src/lib/drag.coffee
new file mode 100644
index 0000000..191aa1e
--- /dev/null
+++ b/src/web/src/lib/drag.coffee
@@ -0,0 +1,95 @@
+#!/usr/bin/env coffee
+
+#import {IS_WIN} from '~/lib/os.coffee'
+import $on from '~/lib/on.coffee'
+import ipc from '~/lib/ipc.coffee'
+
+{drag:{setBounds}} = ipc
+#IS_WIN = true
+pointermove = 'pointermove'
+IGNORE = new Set('SELECT BUTTON A INPUT TEXTAREA'.split ' ')
+{round} = Math
+export default main = (elem)=>
+  #if not IS_WIN
+  #  return
+
+  elem.style.appRegion = 'no-drag'
+
+  moving = false
+
+  init_w = init_h = init_x = init_y = init_top = init_left = undefined
+
+  _move = (e)=>
+    {screenX,screenY} = e
+    setBounds(
+      round screenX-init_x+init_left
+      round screenY-init_y+init_top
+      init_w
+      init_h
+    )
+    return
+
+  mousedown = (e)=>
+    if e.button!=0 # ????
+      return
+    {target} = e
+    #if target.tagName != 'VIDEO'
+    #  return
+    p = e.target
+    loop
+      {nodeName} = p
+      if IGNORE.has nodeName
+        return
+      if nodeName == 'BODY'
+        break
+      p = p.parentNode
+    moving = true
+    {screenX:init_x,screenY:init_y} = e
+
+    elem.setPointerCapture e.pointerId
+    elem.addEventListener pointermove,_move
+
+    init_top = screenTop
+    init_left = screenLeft
+    init_w = outerWidth
+    init_h = outerHeight
+
+    return
+
+  mouseup = (e)=>
+    if moving
+      await _move(e)
+      elem.releasePointerCapture e.pointerId
+      elem.removeEventListener pointermove,_move
+      moving = false
+    return
+
+  $on elem,{
+    lostpointercapture:mouseup
+    pointercancel:mouseup
+    pointerdown:mousedown
+    pointerup:mouseup
+  }
+
+  return
+
+###
+    init_x = init_y = undefined
+
+
+    move = (e)=>
+      {screenX:x,screenY:y} = e
+      await camera.move(x-init_x,y-init_y)
+
+    mousemove = (e)=>
+      await move(e)
+      return
+
+
+
+      await camera.init()
+      moving = true
+
+      return
+
+###
diff --git a/src/web/src/lib/on.coffee b/src/web/src/lib/on.coffee
new file mode 100644
index 0000000..a79b9e7
--- /dev/null
+++ b/src/web/src/lib/on.coffee
@@ -0,0 +1,5 @@
+import $on from './_on.coffee'
+export default (elem, dict)=>
+  unbind = $on elem, dict
+  onUnmounted unbind
+  unbind
diff --git a/src/web/src/page/recbar.vue b/src/web/src/page/recbar.vue
index f853865..d6d6796 100644
--- a/src/web/src/page/recbar.vue
+++ b/src/web/src/page/recbar.vue
@@ -154,7 +154,7 @@ nav.pause > code, code.pause
     background-color transparent
 </style>
 <template lang="pug">
-nav(:class="{ pause }")
+nav(:class="{ pause }" ref="nav")
   template(v-for="([en, cn], pos) in left")
     a(:class="[en, config[en] ? '' : 'x']" :title="cn" @click="go(en)")
   b
@@ -178,7 +178,7 @@ import ipc from '~/lib/ipc.coffee'
 {recbar} = ipc
 import broadcast from '~/lib/broadcast.coffee'
 import ON from '~/lib/broadcast/on.coffee'
-
+import drag from '~/lib/drag.coffee'
 import config from '~/store/record.coffee'
 import {hm} from '~/lib/time.coffee'
 import DRAW from '~/store/draw.coffee'
@@ -282,6 +282,10 @@ cancel ????"""
     local[i] = turn(i)

   draw = shallowRef()
+  nav = shallowRef()
+  onMounted = =>
+    draw(nav.value)
+    return

   {
     go:(en)=>
@@ -301,6 +305,7 @@ cancel ????"""
       (local[en] or recbar[en])()
       return
     left
+    nav
     right
     code
     minute

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 gcxfd