首页 > 其他分享 >electron 无边框窗口拖拽移动问题记录及解决办法

electron 无边框窗口拖拽移动问题记录及解决办法

时间:2023-06-18 14:22:40浏览次数:96  
标签:ipcRenderer move window 拖拽 electron let parseInt 边框 event

在做一款uTools的插件,悬浮文本

image

窗口是没有标题栏的,所以需要找一个地方可以拖动移动位置

就开始了接下来的踩坑记录

项目结构

只是一个简单的容器元素,一个多行文本框

容器元素加一个内边距,然后这个内边距区域就是我理想的可拖动位置

<body>
  <div id="container">
    <textarea id="content" spellcheck="false"></textarea>
  </div>
</body>

实现流程

webkit-app-region

首个版本,我采用CSS很简单便实现了

当时是用 Mac 开发测试的,一切运行良好

#container {
	-webkit-app-region: drag;
	padding: 10px;
	cursor: move;
}

隔天到 Win 上看效果

发现拖动虽然正常,但是光标样式没有了

image

鼠标放在边框位置不会变成移动的光标

经查阅,设置了-webkit-app-region: drag;的元素,不会在响应鼠标事件了(mac上测试的时候正常的)

so,需要继续改了

鼠标事件

没有简便办法了,就只好自己写个鼠标拖拽事件了

按下记录下鼠标相对于窗口的位置

鼠标移动后计算出窗口新的位置

窗口新位置=窗口当前位置+鼠标新的相对位置-鼠标原来的相对位置

主进程 (因为是uTools插件开发,和electron原始代码的监听不一样)

ipcRenderer.on('move', (event, x, y) => {
  ubWindow.setPosition(x, y)
})
// 初始化
ipcRenderer.sendTo(ubWindow.webContents.id, 'init')

webPreferencespreload

const { ipcRenderer } = require('electron')
let winId
ipcRenderer.on('init', (event) => {
	winId = event.senderId
	window.init()
})
window.move = (x, y) => {
	ipcRenderer.sendTo(winId,'move',x, y)
}

页面js

let moveIng = false
let startX = 0
let startY = 0
const move = (event) => {
	if (!moveIng) return
	const x = window.screenX + event.clientX - startX
	const y = window.screenY + event.clientY - startY
	window.move(x, y)
}
//绑定拖拽移动事件
document.addEventListener('mousedown', (event) => {
	if (event.button === 0 && event.target.tagName !== 'TEXTAREA') {
		moveIng = true
		startX = event.clientX
		startY = event.clientY
		document.addEventListener('mousemove', move)
	}
})
document.addEventListener('mouseup', (event) => {
	if (!moveIng) return
	document.removeEventListener('mousemove', move)
	moveIng = false
})

测试,Win和Mac拖拽正常,光标正常

image

But,换电脑在测试时,发现某个Win的电脑移动窗口时,窗口尺寸会不停的变大

甚至只要鼠标按在窗口上,尺寸都可能会改变

so,继续改吧

缩放

经过多次测试和查阅

最终把问题定位在Win的缩放与布局

image

该选项如果是100%测试一点问题都没有

如果每次拖动尺寸会发生改变,那我们就不再使用setPosition改用setBounds

每次调整位置时直接将尺寸也传递进去,修改下代码

主进程

ipcRenderer.on('moveBounds', (event, x, y, width, height) => {
  if (event.senderId == ubWindow.webContents.id) {
    let newBounds = {
      x: parseInt(x),
      y: parseInt(y),
      width: parseInt(width),
      height: parseInt(height),
    }
    ubWindow.setBounds(newBounds)
  }
})
// 初始化
ipcRenderer.sendTo(ubWindow.webContents.id, 'init')

webPreferencespreload

const { ipcRenderer } = require('electron')
let winId
ipcRenderer.on('init', (event) => {
	winId = event.senderId
	window.init()
})
window.moveBounds = (x, y, width, height) => {
	ipcRenderer.sendTo(winId, 'moveBounds', x, y, width, height);
}

页面js

let moveIng = false
let startX = 0
let startY = 0
let lastWidth = 0
let lastHeight = 0
const move = (event) => {
  if (!moveIng) return
  const x = window.screenX + event.clientX - startX
  const y = window.screenY + event.clientY - startY
  window.moveBounds(parseInt(x), parseInt(y), lastWidth, lastHeight)
}
//绑定拖拽移动事件
document.addEventListener('mousedown', (event) => {
  if (event.button === 0 && event.target.tagName !== 'TEXTAREA') {
    moveIng = true
    startX = parseInt(event.clientX)
    startY = parseInt(event.clientY)
    lastWidth = parseInt(window.outerWidth)
    lastHeight = parseInt(window.outerHeight)
    document.addEventListener('mousemove', move)
  }
})
document.addEventListener('mouseup', (event) => {
  if (!moveIng) return
  document.removeEventListener('mousemove', move)
  moveIng = false
})

调整后Win和Mac测试均正常

但如果拖动过快,仔细观察,窗口有时会闪烁

而且文本框中的内容有时会变成选中状态

~ o(* ̄▽ ̄*)o 暂时就酱吧

有大神知道更好解决方案的话可以贴出来观摩下

标签:ipcRenderer,move,window,拖拽,electron,let,parseInt,边框,event
From: https://www.cnblogs.com/jianzhan/p/electron_drag.html

相关文章

  • PySide6(Qt for Python) QTableWidget表头边框线问题
    这个问题是在Windows10平台下特有问题。网络上有很多QtC++的解决方案。但是没有特定的PySide6的解决方案(以下是参考的QtC++的解决方案)。链接:https://blog.csdn.net/qq_22642239/article/details/122863344问题描述C++的解决方案是设置纵横表头的样式表:horizontalHeader,v......
  • Journal of Electronic Imaging投稿分享
    JournalofElectronicImaging投稿分享在研究生阶段中的第一篇论文,前后总共三个月,还是很开心的!!!附下中稿图片 这个期刊从二月份开始投的,然后三月份给了大修,大修时间一个月。在四月份左右提交了修改稿,最终五月份就给了录用通知!总的来说,速度还是很快的。附下两次的审稿进度。......
  • qt——在主窗口顶层显示一个新窗口,要求新窗口没有边框,不在任务栏显示
     entitulist_ui=newUi::Entitylist;equiplist_ui=newUi::Equiplist;m_entityList=newQWidget(this);m_equipList=newQWidget(this);entitulist_ui->setupUi(m_entityList);equiplist_ui->setupUi(m_equipList);//窗体背景透明m_e......
  • 利用react-resizable实现antd表格头宽度可以拖拽调节
    1.创建ResizeAbleTable文件夹1.1index.jsimport{Table}from"antd4"importReact,{useEffect,useState}from"react"import{Resizable}from"react-resizable"import"./index.less"/***可伸缩列*@paramprops*@retur......
  • 修复 winform窗体无边框最大化后遮挡任务栏
    1、设置窗体的最大尺寸MaxinumSize属性:this.MaxinumSize=newSystem.Drawing.Size(System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width,System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height)或2、设置窗体最大化的尺寸MaximizedBounds属性:this.Maximize......
  • 如何解决图片加 border 后图片会和边框有不太明显的界限?
    如上图,给图片加了border后,无论直接给图片加,还是给图片套一个壳子加,都会有一点点不太明显的图片和边框之间的分割线,在手机看尤其明显。勉强看不出来的解决方案:给图片外层加border,给图片的宽高都放大一点点,同时给外层付元素设垂直居中,外层父元素不要写overflow:hidden,这样图......
  • css边框斜角
    为实现下面图形形状<style>.box{width:200px;height:100px;}</style><divclass="box"></div>1、利用linear-gradient.box{background:linear-gradient(135deg,transparent15px,#3b30)topleft,   linear-gradient(-135deg,......
  • vue封装包含区域内不可拖拽的可拖拽组件
    标题比较绕口,大概意思就是封装一个可拖拽组件,但是因为组件内有文件或者表单或者其它原因而不可在这个区域内使用拖拽,所以在绑定拖拽区域方法的同时限制不可拖拽区域。实现方式很简单  直接看代码drag.jsimportVuefrom'vue'exportconstdrag=Vue.directive('drag',{......
  • C# Winform TabControl边框设置
     参考https://stackoverflow.com/questions/2567172/c-sharp-tabcontrol-border-controls  ......
  • 如何制作一个无标题栏且可拖拽的窗口
    如何制作一个无标题栏且可拖拽的窗口默认情况下,我们创建一个窗口自带有一个标题栏,标题栏上有程序的图标和标题,以及最小化、最大化、关闭按钮。默认标题栏的样式比较固定,有时候为了自定义样式,就需要先隐藏默认的标题栏,然后自己制作一个。同时有时还希望修改默认的拖拽窗口的方式......