skip to Main Content

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.

2

Answers


  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.

    Login or Signup to reply.
  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
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search