Xorg无框窗口鼠标拖拽调整大小及边缘光标切换实现问询
在Xorg中实现无框窗口的鼠标拖拽调整大小与光标切换
一、检测鼠标是否处于窗口边缘
首先需要实时追踪鼠标在窗口内的相对位置,判断是否落在预设的边缘阈值区域(通常设为5-10px):
- 调用
XQueryPointer获取鼠标相对于目标窗口的坐标(x, y) - 通过
XGetWindowAttributes获取窗口当前的宽高(width, height) - 依据坐标判断鼠标位置:
- 左边缘:
x < 阈值 - 右边缘:
x > width - 阈值 - 上边缘:
y < 阈值 - 下边缘:
y > height - 阈值 - 角落:上述边缘条件的组合(如左上角:
x < 阈值 && y < 阈值)
- 左边缘:
二、切换resize样式光标
根据鼠标所在的边缘/角落,加载对应系统光标并应用到窗口:
- 使用
XCreateFontCursor创建目标光标,常用常量:- 左右边缘:
XC_sb_h_double_arrow - 上下边缘:
XC_sb_v_double_arrow - 左上/右下角落:
XC_fleur(或XC_top_left_corner/XC_bottom_right_corner) - 右上/左下角落:
XC_top_right_corner/XC_bottom_left_corner
- 左右边缘:
- 用
XDefineCursor将光标绑定到窗口;当鼠标离开边缘区域时,调用XUndefineCursor恢复默认光标,或重新设置XC_left_ptr光标。
三、实现拖拽调整窗口大小
当检测到鼠标在边缘且按下左键时,启动拖拽逻辑:
- 触发
ButtonPress事件时,记录初始鼠标位置(startX, startY)和窗口当前的位置、尺寸(winX, winY, winW, winH) - 监听
MotionNotify事件,计算鼠标移动偏移量dx = currentX - startX、dy = currentY - startY - 根据边缘类型调整窗口参数:
- 左边缘:窗口宽度改为
winW - dx,同时X坐标偏移dx - 右边缘:窗口宽度改为
winW + dx - 上边缘:窗口高度改为
winH - dy,同时Y坐标偏移dy - 下边缘:窗口高度改为
winH + dy - 角落:同时调整宽高与窗口位置
- 左边缘:窗口宽度改为
- 调用
XMoveResizeWindow更新窗口状态;收到ButtonRelease事件时,结束拖拽流程。
关键注意事项
- 必须给窗口设置正确的事件掩码,确保捕获所需事件:
XSelectInput(dpy, win, PointerMotionMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask) - 无框窗口需自行处理所有交互逻辑,窗口管理器通常不提供默认resize支持
- 部分环境下光标常量可能存在差异,可通过
XListFonts(dpy, "cursor:*", 1000, &count, &font_names)查看可用光标字体列表
内容的提问来源于stack exchange,提问作者xMonody
相关产品推荐
相关产品推荐

