Files

1892 lines
63 KiB
C++
Raw Permalink Normal View History

2020-07-30 17:59:34 +08:00
/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*-
* -*- coding: utf-8 -*-
*
* Copyright (C) 2020 KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2020-03-19 18:59:01 +08:00
#include "mouse-manager.h"
#include "clib-syslog.h"
#include "usd_base_class.h"
2020-03-19 18:59:01 +08:00
2020-04-09 16:43:43 +08:00
/* Keys with same names for both touchpad and mouse */
#define KEY_LEFT_HANDED "left-handed" /* a boolean for mouse, an enum for touchpad */
#define KEY_MOTION_ACCELERATION "motion-acceleration"
#define KEY_MOTION_THRESHOLD "motion-threshold"
/* Mouse settings */
#define UKUI_MOUSE_SCHEMA "org.ukui.peripherals-mouse"
#define KEY_MOUSE_LOCATE_POINTER "locate-pointer"
#define KEY_MIDDLE_BUTTON_EMULATION "middle-button-enabled"
2020-09-23 19:40:41 +08:00
#define KEY_MOUSE_WHEEL_SPEED "wheel-speed"
2020-10-19 15:01:29 +08:00
#define KEY_MOUSE_ACCEL "mouse-accel"
2020-04-09 16:43:43 +08:00
/* Touchpad settings */
#define UKUI_TOUCHPAD_SCHEMA "org.ukui.peripherals-touchpad"
#define KEY_TOUCHPAD_DISABLE_W_TYPING "disable-while-typing"
#define KEY_TOUCHPAD_TWO_FINGER_CLICK "two-finger-click"
#define KEY_TOUCHPAD_THREE_FINGER_CLICK "three-finger-click"
#define KEY_TOUCHPAD_NATURAL_SCROLL "natural-scroll"
#define KEY_TOUCHPAD_TAP_TO_CLICK "tap-to-click"
#define KEY_TOUCHPAD_ONE_FINGER_TAP "tap-button-one-finger"
#define KEY_TOUCHPAD_TWO_FINGER_TAP "tap-button-two-finger"
#define KEY_TOUCHPAD_THREE_FINGER_TAP "tap-button-three-finger"
#define KEY_VERT_EDGE_SCROLL "vertical-edge-scrolling"
2020-11-25 14:31:57 +08:00
#define KEY_HORIZ_EDGE_SCROLL "horizontal-edge-scrolling"
2020-04-09 16:43:43 +08:00
#define KEY_VERT_TWO_FINGER_SCROLL "vertical-two-finger-scrolling"
#define KEY_HORIZ_TWO_FINGER_SCROLL "horizontal-two-finger-scrolling"
#define KEY_TOUCHPAD_ENABLED "touchpad-enabled"
#define KEY_TOUCHPAD_DISBLE_O_E_MOUSE "disable-on-external-mouse" //插入鼠标,禁用触摸板 true/false
#define KEY_TOUCHPAD_DOUBLE_CLICK_DRAG "double-click-drag" //点击两次拖动 true/false
#define KEY_TOUCHPAD_BOTTOM_R_C_CLICK_M "bottom-right-corner-click-menu" //右下角点击菜单 true/false
#define KEY_TOUCHPAD_MOUSE_SENSITVITY "mouse-sensitivity" //鼠标敏感度 1-4 四个档位 低中高最高
2021-11-09 14:24:42 +08:00
extern "C"{
#include <X11/extensions/XInput2.h>
}
2020-03-19 18:59:01 +08:00
typedef enum {
TOUCHPAD_HANDEDNESS_RIGHT,
TOUCHPAD_HANDEDNESS_LEFT,
TOUCHPAD_HANDEDNESS_MOUSE
} TouchpadHandedness;
GdkFilterReturn devicepresence_filter (GdkXEvent *xevent,
GdkEvent *event,
gpointer data);
2020-04-17 16:11:58 +08:00
bool supports_xinput_devices (void);
bool touchpad_is_present (void);
2020-04-04 13:52:52 +08:00
2020-03-19 18:59:01 +08:00
MouseManager * MouseManager::mMouseManager =nullptr;
MouseManager::MouseManager(QObject *parent) : QObject (parent)
{
2020-04-03 20:38:30 +08:00
gdk_init(NULL,NULL);
2020-09-23 19:40:41 +08:00
syndaemon_spawned = false;
syndaemon_pid = 0;
locate_pointer_spawned = false;
locate_pointer_pid = 0;
imwheelSpawned = false;
settings_mouse = new QGSettings(UKUI_MOUSE_SCHEMA);
2020-04-03 20:38:30 +08:00
settings_touchpad = new QGSettings(UKUI_TOUCHPAD_SCHEMA);
}
MouseManager::~MouseManager()
{
delete settings_mouse;
delete settings_touchpad;
2020-04-09 16:43:43 +08:00
if(time)
delete time;
2020-03-19 18:59:01 +08:00
}
MouseManager * MouseManager::MouseManagerNew()
{
if(nullptr == mMouseManager)
mMouseManager = new MouseManager(nullptr);
return mMouseManager;
}
2020-04-03 20:38:30 +08:00
bool MouseManager::MouseManagerStart()
2020-03-19 18:59:01 +08:00
{
2021-07-08 20:27:35 +08:00
USD_LOG(LOG_DEBUG,"-- Mouse Start Manager --");
2020-04-03 20:38:30 +08:00
if (!supports_xinput_devices()){
qWarning("XInput is not supported, not applying any settings");
2020-03-19 18:59:01 +08:00
return TRUE;
2020-04-03 20:38:30 +08:00
}
time = new QTimer(this);
2021-07-26 15:34:32 +08:00
connect(time, &QTimer::timeout, this, &MouseManager::MouseManagerIdleCb);
2020-04-03 20:38:30 +08:00
time->start();
2020-03-19 18:59:01 +08:00
return true;
}
void MouseManager::MouseManagerStop()
{
2021-07-08 20:27:35 +08:00
USD_LOG(LOG_DEBUG,"-- Stopping Mouse Manager --");
2020-03-19 18:59:01 +08:00
SetLocatePointer(FALSE);
2020-03-19 18:59:01 +08:00
gdk_window_remove_filter (NULL, devicepresence_filter, this);
}
2020-04-04 13:52:52 +08:00
/* transplant usd-input-helper.h */
2020-08-05 17:07:24 +08:00
/* Checks whether the XInput device is supported
2020-07-25 20:23:33 +08:00
* 检测是否支持xinput设备
*/
2020-04-17 16:11:58 +08:00
bool
2020-04-04 13:52:52 +08:00
supports_xinput_devices (void)
{
2020-04-17 16:11:58 +08:00
int op_code, event, error;
2020-04-04 13:52:52 +08:00
2020-04-17 16:11:58 +08:00
return XQueryExtension (QX11Info::display(),
"XInputExtension",
&op_code,
&event,
&error);
2020-04-04 13:52:52 +08:00
}
2020-04-17 16:11:58 +08:00
static bool
2020-04-04 13:52:52 +08:00
device_has_property (XDevice *device,
const char *property_name)
{
2020-04-17 16:11:58 +08:00
Atom realtype, prop;
int realformat;
unsigned long nitems, bytes_after;
unsigned char *data;
2020-04-04 13:52:52 +08:00
2020-04-17 16:11:58 +08:00
prop = XInternAtom (QX11Info::display(), property_name, True);
if (!prop)
return FALSE;
2020-04-04 13:52:52 +08:00
2020-04-17 16:11:58 +08:00
try {
if ((XGetDeviceProperty (QX11Info::display(), device, prop, 0, 1, False,
XA_INTEGER, &realtype, &realformat, &nitems,
&bytes_after, &data) == Success) && (realtype != None)) {
XFree (data);
return TRUE;
2020-04-04 13:52:52 +08:00
}
2020-04-17 16:11:58 +08:00
} catch (int x) {
}
return FALSE;
2020-04-04 13:52:52 +08:00
}
XDevice* device_is_touchpad (XDeviceInfo *deviceinfo)
{
2020-04-17 16:11:58 +08:00
XDevice *device;
2020-04-04 13:52:52 +08:00
2020-04-17 16:11:58 +08:00
if (deviceinfo->type != XInternAtom (QX11Info::display(), XI_TOUCHPAD, True))
2020-04-04 13:52:52 +08:00
return NULL;
2020-04-17 16:11:58 +08:00
try {
device = XOpenDevice (QX11Info::display(), deviceinfo->id);
2020-07-25 20:23:33 +08:00
if (device == NULL)
2020-04-17 16:11:58 +08:00
throw 1;
if (device_has_property (device, "libinput Tapping Enabled") ||
device_has_property (device, "Synaptics Off")) {
return device;
2020-04-04 13:52:52 +08:00
}
2020-04-17 16:11:58 +08:00
XCloseDevice (QX11Info::display(), device);
} catch (int x) {
2020-04-04 13:52:52 +08:00
return NULL;
2020-04-17 16:11:58 +08:00
}
return NULL;
2020-04-04 13:52:52 +08:00
}
2020-04-17 16:11:58 +08:00
bool touchpad_is_present (void)
2020-04-04 13:52:52 +08:00
{
2020-04-17 16:11:58 +08:00
XDeviceInfo *device_info;
int n_devices;
2020-07-25 20:23:33 +08:00
int i;
2020-04-17 16:11:58 +08:00
bool retval;
2020-04-04 13:52:52 +08:00
2020-07-25 20:23:33 +08:00
if (supports_xinput_devices () == false)
return true;
2020-04-04 13:52:52 +08:00
2020-07-25 20:23:33 +08:00
retval = false;
2020-04-04 13:52:52 +08:00
2020-04-17 16:11:58 +08:00
device_info = XListInputDevices (QX11Info::display(), &n_devices);
if (device_info == NULL)
2020-07-25 20:23:33 +08:00
return false;
2020-04-04 13:52:52 +08:00
2020-04-17 16:11:58 +08:00
for (i = 0; i < n_devices; i++) {
XDevice *device;
2020-04-04 13:52:52 +08:00
2020-04-17 16:11:58 +08:00
device = device_is_touchpad (&device_info[i]);
if (device != NULL) {
2020-07-25 20:23:33 +08:00
retval = true;
2020-04-17 16:11:58 +08:00
break;
}
}
if (device_info != NULL)
XFreeDeviceList (device_info);
2020-04-04 13:52:52 +08:00
2020-04-17 16:11:58 +08:00
return retval;
2020-04-04 13:52:52 +08:00
}
2020-08-05 17:07:24 +08:00
bool MouseManager::GetTouchpadHandedness (bool mouse_left_handed)
2020-03-19 18:59:01 +08:00
{
2020-07-23 09:33:02 +08:00
int a = settings_touchpad->getEnum(KEY_LEFT_HANDED);
2020-04-03 20:38:30 +08:00
2020-04-17 16:11:58 +08:00
switch (a) {
case TOUCHPAD_HANDEDNESS_RIGHT:
return false;
case TOUCHPAD_HANDEDNESS_LEFT:
return true;
case TOUCHPAD_HANDEDNESS_MOUSE:
return mouse_left_handed;
default:
g_assert_not_reached ();
}
2020-03-19 18:59:01 +08:00
}
Atom property_from_name (const char *property_name)
{
2020-04-17 16:11:58 +08:00
return XInternAtom (QX11Info::display(), property_name, True);
2020-03-19 18:59:01 +08:00
}
bool query_device_had_property(XDeviceInfo *device_info,const char *property_name)
{
XDevice *device;
int nProps = 0;
Atom* type_data;
unsigned char *data;
Atom Xdata;
bool ret = false;
Display * display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
device = XOpenDevice (display, device_info->id);
USD_LOG(LOG_DEBUG,"device name:%s",device_info->name);
if (device == NULL) {
USD_LOG(LOG_DEBUG, "%s find %s had a error:can't open id(%d) device in XOpenDevice,type:%d",device_info->name, property_name,device_info->id,device_info->type);
return false;
}
type_data = XListDeviceProperties(display ,device, &nProps);
Xdata = XInternAtom (QX11Info::display(), property_name, True);
//USD_LOG_SHOW_PARAM1(nProps);
//USD_LOG_SHOW_PARAM1(Xdata);
//USD_LOG_SHOW_PARAMS(property_name);
if (Xdata == 0) {
ret = false;
goto END;
}
for (int k = 0; k < nProps; k++) {
// USD_LOG_SHOW_PARAM1(type_data[k]);
if (Xdata == type_data[k]) {
USD_LOG(LOG_DEBUG,"find: props");
//USD_LOG_SHOW_PARAM1(type_data[k]);
ret = true;
goto END;
}
}
END:
XCloseDevice (display, device);
return ret;
}
/* This is an example of the last function.
2020-08-05 17:07:24 +08:00
bool property_exists_on_device (XDeviceInfo *device_info, const char *property_name)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
XDevice *device;
int rc;
Atom type, prop;
int format;
unsigned long nitems, bytes_after;
unsigned char *data;
// Display *display = gdk_x11_get_default_xdisplay ();//QX11Info::display();
Display * display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
2020-04-17 16:11:58 +08:00
prop = property_from_name (property_name);
2021-07-26 15:34:32 +08:00
2020-04-17 16:11:58 +08:00
if (!prop)
2020-04-03 20:38:30 +08:00
return FALSE;
2020-04-17 16:11:58 +08:00
try {
device = XOpenDevice (display, device_info->id);
if (device == NULL) {
USD_LOG(LOG_DEBUG, "%s find %s had a error:can't open id(%d) device in XOpenDevice,type:%d",device_info->name, property_name,device_info->id,device_info->type);
2020-04-17 16:11:58 +08:00
throw 1;
}
// USD_LOG(LOG_DEBUG,"prop [%s] had find in %d type:%d", property_name, device_info->id, device_info->type);
2020-04-17 16:11:58 +08:00
rc = XGetDeviceProperty (display,
device, prop, 0, 1, False, XA_INTEGER, &type, &format,
&nitems, &bytes_after, &data);
USD_LOG_SHOW_PARAM1(rc);
2020-04-17 16:11:58 +08:00
if (rc == Success)
XFree (data);
XCloseDevice (display, device);
} catch (int str) {
2021-07-08 20:27:35 +08:00
USD_LOG(LOG_DEBUG,"MOUSE: WRING ID: %d",str);
2020-04-17 16:11:58 +08:00
return FALSE;
}
2021-07-26 15:34:32 +08:00
2020-04-17 16:11:58 +08:00
return rc == Success;
2020-03-19 18:59:01 +08:00
}
*/
2020-03-19 18:59:01 +08:00
void property_set_bool (XDeviceInfo *device_info,
XDevice *device,
const char *property_name,
int property_index,
2020-04-03 20:38:30 +08:00
bool enabled)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
int rc;
unsigned long nitems, bytes_after;
unsigned char *data;
int act_format;
Atom act_type, property;
2020-07-25 20:23:33 +08:00
Display *display = gdk_x11_get_default_xdisplay ();//QX11Info::display();
2020-04-17 16:11:58 +08:00
property = property_from_name (property_name);
if (!property)
return;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
try {
2020-07-25 20:23:33 +08:00
gdk_x11_display_error_trap_push (gdk_display_get_default());
2020-04-17 16:11:58 +08:00
rc = XGetDeviceProperty (display, device,
property, 0, 1, False,
XA_INTEGER, &act_type, &act_format, &nitems,
&bytes_after, &data);
2020-08-21 15:35:48 +08:00
if (rc == Success && act_type == XA_INTEGER && act_format == 8 && nitems >(unsigned long)property_index) {
2020-04-17 16:11:58 +08:00
data[property_index] = enabled ? 1 : 0;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
XChangeDeviceProperty (display, device,
property, XA_INTEGER, 8,
PropModeReplace, data, nitems);
2020-03-19 18:59:01 +08:00
}
2020-04-17 16:11:58 +08:00
if (rc == Success)
XFree (data);
2020-07-25 20:23:33 +08:00
if(gdk_x11_display_error_trap_pop (gdk_display_get_default()))
USD_LOG(LOG_DEBUG,"Error while setting %s on \"%s\"", property_name, device_info->name);
2020-04-17 16:11:58 +08:00
} catch (int x) {
2021-07-08 20:27:35 +08:00
USD_LOG(LOG_DEBUG,"MOUSE:Error while setting %s on \"%s\"", property_name, device_info->name)
2020-04-17 16:11:58 +08:00
}
2020-03-19 18:59:01 +08:00
}
void set_left_handed_libinput (XDeviceInfo *device_info,
2020-04-03 20:38:30 +08:00
bool mouse_left_handed,
bool touchpad_left_handed)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
XDevice *device;
bool want_lefthanded;
Display *display = QX11Info::display();
device = device_is_touchpad (device_info);
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
try {
if (device == NULL) {
device = XOpenDevice (display, device_info->id);
if (device == NULL)
throw 1;
2020-04-03 20:38:30 +08:00
2020-04-17 16:11:58 +08:00
want_lefthanded = mouse_left_handed;
} else {
/* touchpad device is already open after
* return from device_is_touchpad function
*/
want_lefthanded = touchpad_left_handed;
2020-03-19 18:59:01 +08:00
}
2020-04-17 16:11:58 +08:00
property_set_bool (device_info, device, "libinput Left Handed Enabled", 0, want_lefthanded);
XCloseDevice (display, device);
} catch (int x) {
return;
}
2020-03-19 18:59:01 +08:00
}
gboolean xinput_device_has_buttons (XDeviceInfo *device_info)
{
2020-04-17 16:11:58 +08:00
int i;
XAnyClassInfo *class_info;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
class_info = device_info->inputclassinfo;
for (i = 0; i < device_info->num_classes; i++) {
if (class_info->c_class == ButtonClass) {
XButtonInfo *button_info;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
button_info = (XButtonInfo *) class_info;
if (button_info->num_buttons > 0)
return TRUE;
}
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
class_info = (XAnyClassInfo *) (((guchar *) class_info) +
class_info->length);
}
return FALSE;
2020-03-19 18:59:01 +08:00
}
2020-04-03 20:38:30 +08:00
bool touchpad_has_single_button (XDevice *device)
2020-03-19 18:59:01 +08:00
{
Atom type, prop;
int format;
unsigned long nitems, bytes_after;
unsigned char *data;
2020-04-03 20:38:30 +08:00
bool is_single_button = FALSE;
2020-03-19 18:59:01 +08:00
int rc;
prop = property_from_name ("Synaptics Capabilities");
if (!prop)
2020-04-03 20:38:30 +08:00
return false;
2020-03-19 18:59:01 +08:00
2020-04-03 20:38:30 +08:00
try {
rc = XGetDeviceProperty (QX11Info::display(), device, prop, 0, 1, False,
XA_INTEGER, &type, &format, &nitems,
&bytes_after, &data);
if (rc == Success && type == XA_INTEGER && format == 8 && nitems >= 3)
is_single_button = (data[0] == 1 && data[1] == 0 && data[2] == 0);
2020-03-19 18:59:01 +08:00
2020-04-03 20:38:30 +08:00
if (rc == Success)
XFree (data);
} catch (int x) {
2020-03-19 18:59:01 +08:00
2020-04-03 20:38:30 +08:00
}
2020-03-19 18:59:01 +08:00
return is_single_button;
}
void set_tap_to_click_synaptics (XDeviceInfo *device_info,
2020-04-03 20:38:30 +08:00
bool state,
bool left_handed,
2020-04-17 16:11:58 +08:00
int one_finger_tap,
int two_finger_tap,
int three_finger_tap)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
XDevice *device;
int format, rc;
unsigned long nitems, bytes_after;
unsigned char* data;
Atom prop, type;
2020-07-25 20:23:33 +08:00
Display *display = gdk_x11_get_default_xdisplay (); //QX11Info::display();
2020-04-17 16:11:58 +08:00
prop = property_from_name ("Synaptics Tap Action");
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
if (!prop)
return;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
device = device_is_touchpad (device_info);
if (device == NULL) {
return;
}
try {
rc = XGetDeviceProperty (display, device, prop, 0, 2,
False, XA_INTEGER, &type, &format, &nitems,
&bytes_after, &data);
if (one_finger_tap > 3 || one_finger_tap < 1)
one_finger_tap = 1;
if (two_finger_tap > 3 || two_finger_tap < 1)
two_finger_tap = 3;
if (three_finger_tap > 3 || three_finger_tap < 0)
three_finger_tap = 0;
2020-04-17 16:11:58 +08:00
if (rc == Success && type == XA_INTEGER && format == 8 && nitems >= 7)
{
/* Set RLM mapping for 1/2/3 fingers*/
data[4] = (state) ? ((left_handed) ? (4-one_finger_tap) : one_finger_tap) : 0;
data[5] = (state) ? ((left_handed) ? (4-two_finger_tap) : two_finger_tap) : 0;
data[6] = (state) ? three_finger_tap : 0;
XChangeDeviceProperty (display, device, prop, XA_INTEGER, 8,
PropModeReplace, data, nitems);
2020-03-19 18:59:01 +08:00
}
2020-04-17 16:11:58 +08:00
if (rc == Success)
XFree (data);
2020-03-19 18:59:01 +08:00
USD_LOG(LOG_DEBUG,"...");
2020-04-17 16:11:58 +08:00
XCloseDevice (display, device);
} catch (int x) {
qWarning("Error in setting tap to click on \"%s\"", device_info->name);
2020-04-17 16:11:58 +08:00
}
2020-03-19 18:59:01 +08:00
}
void configure_button_layout (guchar *buttons,
2020-04-17 16:11:58 +08:00
int n_buttons,
bool left_handed)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
const int left_button = 1;
int right_button;
int i;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
/* if the button is higher than 2 (3rd button) then it's
* probably one direction of a scroll wheel or something else
* uninteresting
*/
right_button = MIN (n_buttons, 3);
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
/* If we change things we need to make sure we only swap buttons.
* If we end up with multiple physical buttons assigned to the same
* logical button the server will complain. This code assumes physical
* button 0 is the physical left mouse button, and that the physical
* button other than 0 currently assigned left_button or right_button
* is the physical right mouse button.
*/
/* check if the current mapping satisfies the above assumptions */
if (buttons[left_button - 1] != left_button &&
buttons[left_button - 1] != right_button)
/* The current mapping is weird. Swapping buttons is probably not a
* good idea.
*/
return;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
/* check if we are left_handed and currently not swapped */
if (left_handed && buttons[left_button - 1] == left_button) {
/* find the right button */
for (i = 0; i < n_buttons; i++) {
if (buttons[i] == right_button) {
buttons[i] = left_button;
break;
}
}
/* swap the buttons */
buttons[left_button - 1] = right_button;
}
/* check if we are not left_handed but are swapped */
else if (!left_handed && buttons[left_button - 1] == right_button) {
/* find the right button */
for (i = 0; i < n_buttons; i++) {
if (buttons[i] == left_button) {
buttons[i] = right_button;
break;
}
}
/* swap the buttons */
buttons[left_button - 1] = left_button;
}
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetLeftHandedLegacyDriver (XDeviceInfo *device_info,
bool mouse_left_handed,
bool touchpad_left_handed)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
XDevice *device;
unsigned char *buttons;
unsigned long buttons_capacity = 16;
int n_buttons;
bool left_handed;
Display *display = QX11Info::display();
if ((device_info->use == IsXPointer) ||
(device_info->use == IsXKeyboard) ||
(g_strcmp0 ("Virtual core XTEST pointer", device_info->name) == 0) ||
(!xinput_device_has_buttons (device_info)))
return;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
/* If the device is a touchpad, swap tap buttons
* around too, otherwise a tap would be a right-click */
device = device_is_touchpad (device_info);
if (device != NULL) {
bool tap = settings_touchpad->get(KEY_TOUCHPAD_TAP_TO_CLICK).toBool();
2020-04-17 16:11:58 +08:00
bool single_button = touchpad_has_single_button (device);
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
left_handed = touchpad_left_handed;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
if (tap && !single_button) {
int one_finger_tap = settings_touchpad->get(KEY_TOUCHPAD_ONE_FINGER_TAP).toInt();
int two_finger_tap = settings_touchpad->get(KEY_TOUCHPAD_TWO_FINGER_TAP).toInt();
int three_finger_tap = settings_touchpad->get(KEY_TOUCHPAD_THREE_FINGER_TAP).toInt();
USD_LOG_SHOW_PARAM1(left_handed);
2020-04-17 16:11:58 +08:00
set_tap_to_click_synaptics (device_info, tap, left_handed, one_finger_tap, two_finger_tap, three_finger_tap);
2020-04-03 20:38:30 +08:00
}
2020-03-19 18:59:01 +08:00
2020-04-03 20:38:30 +08:00
XCloseDevice (display, device);
2020-04-17 16:11:58 +08:00
if (single_button)
return;
} else {
left_handed = mouse_left_handed;
USD_LOG(LOG_DEBUG,"SET IT");
USD_LOG_SHOW_PARAM1(left_handed);
//USD_LOG(LOG_DEBUG,".");
2020-04-17 16:11:58 +08:00
}
2020-04-03 20:38:30 +08:00
2020-04-17 16:11:58 +08:00
try {
device = XOpenDevice (display, device_info->id);
if (device == NULL)
throw 1;
buttons = g_new (guchar, buttons_capacity);
n_buttons = XGetDeviceButtonMapping (display, device,
buttons,
buttons_capacity);
2020-08-21 15:35:48 +08:00
while (n_buttons > (int)buttons_capacity) {
2020-04-17 16:11:58 +08:00
buttons_capacity = n_buttons;
buttons = (guchar *) g_realloc (buttons,
buttons_capacity * sizeof (guchar));
n_buttons = XGetDeviceButtonMapping (display, device,
buttons,
buttons_capacity);
2020-03-19 18:59:01 +08:00
}
2020-04-17 16:11:58 +08:00
configure_button_layout (buttons, n_buttons, left_handed);
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
XSetDeviceButtonMapping (display, device, buttons, n_buttons);
XCloseDevice (display, device);
g_free (buttons);
} catch (int x) {
2021-07-08 20:27:35 +08:00
USD_LOG(LOG_DEBUG,"MOUSE :error id %d",x);
2020-04-17 16:11:58 +08:00
return;
}
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetLeftHanded (XDeviceInfo *device_info,
2020-04-17 16:11:58 +08:00
bool mouse_left_handed,
bool touchpad_left_handed)
2020-03-19 18:59:01 +08:00
{
if (query_device_had_property (device_info, "libinput Left Handed Enabled")){
2020-04-17 16:11:58 +08:00
set_left_handed_libinput (device_info, mouse_left_handed, touchpad_left_handed);
USD_LOG_SHOW_PARAM1(mouse_left_handed);
2021-09-22 11:37:53 +08:00
} else {
USD_LOG_SHOW_PARAM1(touchpad_left_handed);
SetLeftHandedLegacyDriver (device_info, mouse_left_handed, touchpad_left_handed);
2021-09-22 11:37:53 +08:00
}
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetLeftHandedAll (bool mouse_left_handed,
bool touchpad_left_handed)
2020-03-19 18:59:01 +08:00
{
2020-08-25 19:07:22 +08:00
XDeviceInfo *device_info = nullptr;
2020-04-17 16:11:58 +08:00
int n_devices;
int i;
Display * dpy = QX11Info::display();
device_info = XListInputDevices (dpy, &n_devices);
2020-08-25 19:07:22 +08:00
if(!device_info){
qWarning("SetLeftHandedAll: device_info is null");
2020-08-25 19:07:22 +08:00
return;
}
2020-04-17 16:11:58 +08:00
for (i = 0; i < n_devices; i++) {
SetLeftHanded (&device_info[i], mouse_left_handed, touchpad_left_handed);
2020-04-17 16:11:58 +08:00
}
if (device_info != NULL)
XFreeDeviceList (device_info);
2020-03-19 18:59:01 +08:00
}
2021-07-26 15:34:32 +08:00
void MouseManager::SetMotionLibinput (XDeviceInfo *device_info)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
XDevice *device;
Atom prop;
Atom type;
Atom float_type;
int format, rc;
unsigned long nitems, bytes_after;
QGSettings *settings;
2020-04-03 20:38:30 +08:00
2020-08-05 17:07:24 +08:00
Display * dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());// gdk_x11_get_default_xdisplay ();//QX11Info::display();
2020-04-03 20:38:30 +08:00
2020-04-17 16:11:58 +08:00
union {
unsigned char *c;
long *l;
} data;
float accel;
float motion_acceleration;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
float_type = property_from_name ("FLOAT");
if (!float_type)
return;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
prop = property_from_name ("libinput Accel Speed");
if (!prop) {
return;
}
try {
device = device_is_touchpad (device_info);
if (device != NULL) {
2021-11-22 15:30:58 +08:00
USD_LOG(LOG_DEBUG,"device != NULL settings = settings_touchpad");
settings = settings_touchpad;
2020-04-17 16:11:58 +08:00
} else {
device = XOpenDevice (dpy, device_info->id);
if (device == NULL)
throw 1;
settings = settings_mouse;
2020-03-19 18:59:01 +08:00
}
2020-04-17 16:11:58 +08:00
/* Calculate acceleration */
2020-08-05 17:07:24 +08:00
motion_acceleration = settings->get(KEY_MOTION_ACCELERATION).toDouble();
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
/* panel gives us a range of 1.0-10.0, map to libinput's [-1, 1]
*
* oldrange = (oldmax - oldmin)
* newrange = (newmax - newmin)
*
* mapped = (value - oldmin) * newrange / oldrange + oldmin
*/
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
if (motion_acceleration == -1.0) /* unset */
accel = 0.0;
else
accel = (motion_acceleration - 1.0) * 2.0 / 9.0 - 1;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
rc = XGetDeviceProperty (dpy,device, prop, 0, 1, False, float_type, &type,
&format, &nitems, &bytes_after, &data.c);
2020-10-19 15:01:29 +08:00
2020-04-17 16:11:58 +08:00
if (rc == Success && type == float_type && format == 32 && nitems >= 1) {
*(float *) data.l = accel;
XChangeDeviceProperty (dpy, device, prop, float_type, 32,
PropModeReplace, data.c, nitems);
2020-03-19 18:59:01 +08:00
}
2020-04-17 16:11:58 +08:00
if (rc == Success) {
XFree (data.c);
}
XCloseDevice (dpy, device);
} catch (int x) {
qWarning("%s Error while setting accel speed on \"%s\"", device_info->name);
2020-04-17 16:11:58 +08:00
return;
}
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetMotionLegacyDriver (XDeviceInfo *device_info)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
XDevice *device;
XPtrFeedbackControl feedback;
XFeedbackState *states, *state;
int num_feedbacks, i;
QGSettings *settings;
double motion_acceleration;
int motion_threshold;
int numerator, denominator;
2020-04-03 20:38:30 +08:00
2020-07-25 20:23:33 +08:00
Display * dpy = gdk_x11_get_default_xdisplay ();//QX11Info::display();
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
device = device_is_touchpad (device_info);
if (device != NULL) {
settings = settings_touchpad;
2020-04-17 16:11:58 +08:00
} else {
try {
device = XOpenDevice (dpy, device_info->id);
if (device == NULL)
throw 1;
} catch (int x) {
2021-07-08 20:27:35 +08:00
USD_LOG(LOG_DEBUG,"%s: error id %d","MOUSE", x);
2020-04-17 16:11:58 +08:00
return;
}
settings = settings_mouse;
2020-04-17 16:11:58 +08:00
}
/* Calculate acceleration */
2020-08-05 17:07:24 +08:00
motion_acceleration = settings->get(KEY_MOTION_ACCELERATION).toDouble();
2020-04-17 16:11:58 +08:00
if (motion_acceleration >= 1.0) {
/* we want to get the acceleration, with a resolution of 0.5
*/
if ((motion_acceleration - floor (motion_acceleration)) < 0.25) {
numerator = floor (motion_acceleration);
denominator = 1;
} else if ((motion_acceleration - floor (motion_acceleration)) < 0.5) {
numerator = ceil (2.0 * motion_acceleration);
denominator = 2;
} else if ((motion_acceleration - floor (motion_acceleration)) < 0.75) {
numerator = floor (2.0 *motion_acceleration);
denominator = 2;
} else {
numerator = ceil (motion_acceleration);
denominator = 1;
2020-04-03 20:38:30 +08:00
}
2020-04-17 16:11:58 +08:00
} else if (motion_acceleration < 1.0 && motion_acceleration > 0) {
/* This we do to 1/10ths */
numerator = floor (motion_acceleration * 10) + 1;
denominator= 10;
} else {
numerator = -1;
denominator = -1;
}
/* And threshold */
motion_threshold = settings->get(KEY_MOTION_THRESHOLD).toInt();
2021-07-21 17:38:15 +08:00
// qDebug()<<__func__<<" motion_threshold = "<<motion_threshold;
USD_LOG(LOG_DEBUG,"motion_threshold:%d", motion_threshold);
2020-04-17 16:11:58 +08:00
/* Get the list of feedbacks for the device */
states = XGetFeedbackControl (dpy, device, &num_feedbacks);
if (states == NULL) {
XCloseDevice (dpy, device);
return;
}
state = (XFeedbackState *) states;
for (i = 0; i < num_feedbacks; i++) {
if (state->c_class == PtrFeedbackClass) {
/* And tell the device */
feedback.c_class = PtrFeedbackClass;
feedback.length = sizeof (XPtrFeedbackControl);
feedback.id = state->id;
feedback.threshold = motion_threshold;
feedback.accelNum = numerator;
feedback.accelDenom = denominator;
2021-07-21 17:38:15 +08:00
USD_LOG(LOG_DEBUG,"Setting accel %d/%d, threshold %d for device '%s'",
2020-04-17 16:11:58 +08:00
numerator, denominator, motion_threshold, device_info->name);
XChangeFeedbackControl (dpy,
device,
DvAccelNum | DvAccelDenom | DvThreshold,
(XFeedbackControl *) &feedback);
break;
2020-03-19 18:59:01 +08:00
}
2020-04-17 16:11:58 +08:00
state = (XFeedbackState *) ((char *) state + state->length);
}
XFreeFeedbackList (states);
XCloseDevice (dpy, device);
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetTouchpadMotionAccel(XDeviceInfo *device_info)
{
XDevice *device;
Atom prop;
Atom type;
Atom float_type;
int format, rc;
unsigned long nitems, bytes_after;
2021-09-22 11:37:53 +08:00
// Display * dpy = gdk_x11_get_default_xdisplay ();//QX11Info::display();
Display * dpy = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());//Display * dpy = QX11Info::display();
union {
unsigned char *c;
long *l;
} data;
float accel;
float motion_acceleration;
float_type = property_from_name ("FLOAT");
if (!float_type)
return;
prop = property_from_name ("Device Accel Constant Deceleration");
if (!prop) {
return;
}
try {
device = device_is_touchpad (device_info);
if (device == NULL)
return;
/* Calculate acceleration */
motion_acceleration = settings_touchpad->get(KEY_MOTION_ACCELERATION).toDouble();
if (motion_acceleration == -1.0) /* unset */
accel = 0.0;
else
accel = motion_acceleration;
rc = XGetDeviceProperty (dpy,device, prop, 0, 1, False, float_type, &type,
&format, &nitems, &bytes_after, &data.c);
2021-11-22 15:30:58 +08:00
USD_LOG_SHOW_PARAM2(format,nitems)
if (rc == Success && type == float_type && format == 32 && nitems >= 1) {
*(float *) data.l = accel;
XChangeDeviceProperty (dpy, device, prop, float_type, 32,
PropModeReplace, data.c, nitems);
}
if (rc == Success) {
XFree (data.c);
}
XCloseDevice (dpy, device);
} catch (int x) {
2021-07-21 17:38:15 +08:00
USD_LOG(LOG_ERR,"catch a bug...");
return;
}
}
2020-10-19 15:01:29 +08:00
void MouseManager::SetMouseAccel(XDeviceInfo *device_info)
{
XDevice *device;
Atom prop;
Atom type;
int format, rc;
unsigned long nitems, bytes_after;
2020-03-19 18:59:01 +08:00
2021-09-27 10:30:23 +08:00
//Display * dpy = QX11Info::display();
Display * dpy = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
2020-10-19 15:01:29 +08:00
unsigned char *data;
bool MouseAccel;
prop = property_from_name ("libinput Accel Profile Enabled");
if (!prop) {
return;
}
try {
device = XOpenDevice (dpy, device_info->id);
if (device == NULL)
throw 1;
rc = XGetDeviceProperty (dpy,device, prop, 0, 2, False, XA_INTEGER, &type,
&format, &nitems, &bytes_after, &data);
if (rc == Success && type == XA_INTEGER && format == 8 && nitems >= 1) {
MouseAccel = settings_mouse->get(KEY_MOUSE_ACCEL).toBool();
if(MouseAccel){
data[0] = 1;
data[1] = 0;
}else{
data[0] = 0;
data[1] = 1;
}
XChangeDeviceProperty (dpy, device, prop, XA_INTEGER, 8,
PropModeReplace, data, nitems);
}
if (rc == Success) {
XFree (data);
}
XCloseDevice (dpy, device);
} catch (int x) {
2021-07-21 17:38:15 +08:00
USD_LOG(LOG_ERR,"catch a bug...");
// qWarning("%s Error while setting accel speed on \"%s\"", device_info->name);
2020-10-19 15:01:29 +08:00
return;
}
}
2021-07-21 17:38:15 +08:00
void MouseManager::SetMotion (XDeviceInfo *device_info)
2020-03-19 18:59:01 +08:00
{
if (query_device_had_property (device_info, "libinput Accel Speed")) {
2021-09-22 11:37:53 +08:00
SetMotionLibinput (device_info);
2021-07-21 17:38:15 +08:00
}
else {
SetMotionLegacyDriver (device_info);
2021-07-21 17:38:15 +08:00
}
if(query_device_had_property (device_info, "Device Accel Constant Deceleration")) {
2021-09-22 11:37:53 +08:00
SetTouchpadMotionAccel(device_info);
2021-07-21 17:38:15 +08:00
}
if(query_device_had_property (device_info, "libinput Accel Profile Enabled")) {
2021-09-22 11:37:53 +08:00
SetMouseAccel(device_info);
2020-10-19 15:01:29 +08:00
}
2020-03-19 18:59:01 +08:00
}
2021-07-21 17:38:15 +08:00
void MouseManager::SetMotionAll()
2020-03-19 18:59:01 +08:00
{
2020-08-25 19:07:22 +08:00
XDeviceInfo *device_info = nullptr;
2020-04-17 16:11:58 +08:00
int n_devices;
int i;
2020-03-19 18:59:01 +08:00
2020-08-05 17:07:24 +08:00
device_info = XListInputDevices (gdk_x11_get_default_xdisplay (), &n_devices);
2020-08-25 19:07:22 +08:00
if(!device_info){
qWarning("SetMotionAll: device_info is null");
2020-08-25 19:07:22 +08:00
return;
}
2020-04-17 16:11:58 +08:00
for (i = 0; i < n_devices; i++) {
SetMotion (&device_info[i]);
2020-04-17 16:11:58 +08:00
}
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
if (device_info != NULL)
XFreeDeviceList (device_info);
2020-03-19 18:59:01 +08:00
}
void set_middle_button_evdev (XDeviceInfo *device_info,
2020-04-17 16:11:58 +08:00
bool middle_button)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
XDevice *device;
Atom prop;
Atom type;
int format, rc;
unsigned long nitems, bytes_after;
unsigned char *data;
2020-03-19 18:59:01 +08:00
Display * display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
// Display * display = QX11Info::display();
2020-04-17 16:11:58 +08:00
prop = property_from_name ("Evdev Middle Button Emulation");
if (!prop) /* no evdev devices */
return;
try {
device = XOpenDevice (display, device_info->id);
if (device == NULL)
throw 1;
rc = XGetDeviceProperty (display,
device, prop, 0, 1, False, XA_INTEGER, &type, &format,
&nitems, &bytes_after, &data);
2020-04-03 20:38:30 +08:00
2020-04-17 16:11:58 +08:00
if (rc == Success && format == 8 && type == XA_INTEGER && nitems == 1) {
2020-10-19 15:01:29 +08:00
data[0] = middle_button ? 1 : 0;
XChangeDeviceProperty (display, device, prop, type, format, PropModeReplace, data, nitems);
2020-03-19 18:59:01 +08:00
}
2020-04-17 16:11:58 +08:00
if (rc == Success)
2020-10-19 15:01:29 +08:00
XFree (data);
2020-04-17 16:11:58 +08:00
XCloseDevice (display, device);
} catch (int x) {
qWarning("Error in setting middle button emulation on \"%s\"", device_info->name);
2020-04-17 16:11:58 +08:00
return;
}
2020-03-19 18:59:01 +08:00
}
void set_middle_button_libinput (XDeviceInfo *device_info,
2020-04-17 16:11:58 +08:00
bool middle_button)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
XDevice *device;
Display *display = QX11Info::display();
/* touchpad devices are excluded as the old code
* only applies to evdev devices
*/
device = device_is_touchpad (device_info);
if (device != NULL) {
2020-04-03 20:38:30 +08:00
try {
XCloseDevice (display, device);
} catch (int x) {
2020-04-17 16:11:58 +08:00
return;
2020-04-03 20:38:30 +08:00
}
2020-04-17 16:11:58 +08:00
}
try {
device = XOpenDevice (display, device_info->id);
if (device == NULL)
throw 1;
property_set_bool (device_info, device, "libinput Middle Emulation Enabled", 0, middle_button);
XCloseDevice (display, device);
} catch (int x) {
2021-07-08 20:27:35 +08:00
USD_LOG(LOG_DEBUG,"%s:error id %d","MOUSE",x);
2020-04-17 16:11:58 +08:00
return;
}
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetMiddleButton (XDeviceInfo *device_info,
bool middle_button)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
if (property_from_name ("Evdev Middle Button Emulation"))
set_middle_button_evdev (device_info, middle_button);
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
if (property_from_name ("libinput Middle Emulation Enabled"))
set_middle_button_libinput (device_info, middle_button);
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetMiddleButtonAll (bool middle_button)
2020-03-19 18:59:01 +08:00
{
2020-08-25 19:07:22 +08:00
XDeviceInfo *device_info = nullptr;
2020-04-17 16:11:58 +08:00
int n_devices;
int i;
Display * display = QX11Info::display();
device_info = XListInputDevices (display, &n_devices);
2020-08-25 19:07:22 +08:00
if(!device_info){
qWarning("SetMiddleButtonAll: device_info is null");
2020-08-25 19:07:22 +08:00
return;
}
2020-04-17 16:11:58 +08:00
for (i = 0; i < n_devices; i++) {
SetMiddleButton (&device_info[i], middle_button);
2020-04-17 16:11:58 +08:00
}
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
if (device_info != NULL)
XFreeDeviceList (device_info);
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetLocatePointer (bool state)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
if (state) {
GError *error = NULL;
2020-08-21 15:35:48 +08:00
char **args;
int argc;
2020-03-19 18:59:01 +08:00
if (locate_pointer_spawned)
2020-08-21 15:35:48 +08:00
return;
QString str = "/usr/bin/usd-locate-pointer";
if( g_shell_parse_argv (str.toLatin1().data(), &argc, &args, NULL)){
g_spawn_async (g_get_home_dir (),
args,
NULL,
G_SPAWN_SEARCH_PATH,
NULL,
NULL,
&locate_pointer_pid,
2020-08-21 15:35:48 +08:00
&error);
locate_pointer_spawned = (error == NULL);
2020-08-21 15:35:48 +08:00
}
2020-04-17 16:11:58 +08:00
if (error) {
settings_mouse->set(KEY_MOUSE_LOCATE_POINTER,false);
2020-04-17 16:11:58 +08:00
g_error_free (error);
2020-03-19 18:59:01 +08:00
}
2020-08-21 15:35:48 +08:00
g_strfreev (args);
} else if (locate_pointer_spawned) {
kill (locate_pointer_pid, SIGHUP);
g_spawn_close_pid (locate_pointer_pid);
locate_pointer_spawned = FALSE;
2020-04-17 16:11:58 +08:00
}
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetMouseWheelSpeed (int speed)
2020-09-23 19:40:41 +08:00
{
2020-10-27 09:39:04 +08:00
if(speed <= 0 )
return;
2020-09-23 19:40:41 +08:00
GPid pid;
QDir dir;
QString FilePath = dir.homePath() + "/.imwheelrc";
QFile file;
int delay = 240000 / speed;
QString date = QString("\".*\"\n"
"Control_L, Up, Control_L|Button4\n"
"Control_R, Up, Control_R|Button4\n"
"Control_L, Down, Control_L|Button5\n"
"Control_R, Down, Control_R|Button5\n"
"Shift_L, Up, Shift_L|Button4\n"
"Shift_R, Up, Shift_R|Button4\n"
"Shift_L, Down, Shift_L|Button5\n"
"Shift_R, Down, Shift_R|Button5\n"
"None, Up, Button4, %1, 0, %2\n"
"None, Down, Button5, %3, 0, %4\n"
"None, Thumb1, Alt_L|Left\n"
"None, Thumb2, Alt_L|Right")
2020-09-23 19:40:41 +08:00
.arg(speed).arg(delay).arg(speed).arg(delay);
file.setFileName(FilePath);
if(file.open(QIODevice::WriteOnly | QIODevice::Text)){
file.write(date.toLatin1().data());
}
GError *error = NULL;
char **args;
int argc;
// if (imwheelSpawned){
// QProcess::execute("killall imwheel");
// imwheelSpawned = false;
// }
2020-09-23 19:40:41 +08:00
QString str = "/usr/bin/imwheel -k";
2020-09-23 19:40:41 +08:00
if( g_shell_parse_argv (str.toLatin1().data(), &argc, &args, NULL)){
g_spawn_async (g_get_home_dir (),
args,
NULL,
G_SPAWN_SEARCH_PATH,
NULL,
NULL,
&pid,
&error);
imwheelSpawned = (error == NULL);
2020-09-23 19:40:41 +08:00
}
file.close();
g_strfreev (args);
}
2020-08-05 17:07:24 +08:00
void MouseManager::MouseCallback (QString keys)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
if (keys.compare(QString::fromLocal8Bit(KEY_LEFT_HANDED))==0){
bool mouse_left_handed = settings_mouse->get(keys).toBool();
2020-08-05 17:07:24 +08:00
bool touchpad_left_handed = GetTouchpadHandedness (mouse_left_handed);
SetLeftHandedAll (mouse_left_handed, touchpad_left_handed);
USD_LOG(LOG_DEBUG,"...............");
SetTapToClickAll ();
2020-10-19 15:01:29 +08:00
} else if ((keys.compare(QString::fromLocal8Bit(KEY_MOTION_ACCELERATION))==0) ||
(keys.compare(QString::fromLocal8Bit(KEY_MOTION_THRESHOLD))==0) ||
(keys.compare(QString::fromLocal8Bit(KEY_MOUSE_ACCEL)) == 0)){
SetMotionAll ();
2020-04-17 16:11:58 +08:00
} else if (keys.compare(QString::fromLocal8Bit(KEY_MIDDLE_BUTTON_EMULATION))==0){
SetMiddleButtonAll (settings_mouse->get(keys).toBool());
2020-04-03 20:38:30 +08:00
2020-04-17 16:11:58 +08:00
} else if (keys.compare(QString::fromLocal8Bit(KEY_MOUSE_LOCATE_POINTER))==0){
SetLocatePointer (settings_mouse->get(keys).toBool());
2020-09-23 19:40:41 +08:00
} else if(keys.compare(QString::fromLocal8Bit(KEY_MOUSE_WHEEL_SPEED)) == 0 ) {
SetMouseWheelSpeed (settings_mouse->get(keys).toInt());
}else{
USD_LOG(LOG_DEBUG,"keys:is skip..k%s", keys.toLatin1().data());
2020-04-17 16:11:58 +08:00
}
2020-03-19 18:59:01 +08:00
}
gboolean have_program_in_path (const char *name)
{
2020-04-17 16:11:58 +08:00
char *path;
bool result;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
path = g_find_program_in_path (name);
result = (path != NULL);
g_free (path);
return result;
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetDisableWTypingSynaptics (bool state)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
if (state && touchpad_is_present ()) {
GError *error = NULL;
2020-08-21 15:35:48 +08:00
char **args;
int argc;
2021-09-22 11:37:53 +08:00
QString cmd = "syndaemon -i 0.3 -K -R";
2021-09-28 18:02:41 +08:00
2021-09-22 11:37:53 +08:00
if (syndaemon_spawned) {
kill (syndaemon_pid, SIGHUP);
g_spawn_close_pid (syndaemon_pid);
syndaemon_spawned = FALSE;
USD_LOG(LOG_DEBUG,"stop syndaemon");
2021-09-22 11:37:53 +08:00
}
2020-08-21 15:35:48 +08:00
2021-10-11 19:03:58 +08:00
if (!have_program_in_path ("syndaemon")) {
return;
}
2020-08-21 15:35:48 +08:00
if (g_shell_parse_argv (cmd.toLatin1().data(), &argc, &args, NULL)) {
g_spawn_async (g_get_home_dir (),
args,
NULL,
G_SPAWN_SEARCH_PATH,
NULL,
NULL,
&syndaemon_pid,
2020-08-21 15:35:48 +08:00
&error);
syndaemon_spawned = (error == NULL);
2020-08-21 15:35:48 +08:00
}
USD_LOG(LOG_DEBUG,"start syndaemon(%d)", syndaemon_pid);
2020-04-17 16:11:58 +08:00
if (error) {
settings_touchpad->set(KEY_TOUCHPAD_DISABLE_W_TYPING,false);
USD_LOG(LOG_ERR,"find error %s",error->message);
2020-04-17 16:11:58 +08:00
g_error_free (error);
2020-03-19 18:59:01 +08:00
}
2021-09-28 18:02:41 +08:00
2020-08-21 15:35:48 +08:00
g_strfreev (args);
2020-04-17 16:11:58 +08:00
2021-09-28 18:02:41 +08:00
} else if (syndaemon_spawned) {
kill (syndaemon_pid, SIGHUP);
g_spawn_close_pid (syndaemon_pid);
syndaemon_spawned = FALSE;
2020-04-17 16:11:58 +08:00
}
2020-03-19 18:59:01 +08:00
}
void touchpad_set_bool (XDeviceInfo *device_info,
const char *property_name,
int property_index,
2020-04-03 20:38:30 +08:00
bool enabled)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
XDevice *device;
2020-04-03 20:38:30 +08:00
2020-04-17 16:11:58 +08:00
device = device_is_touchpad (device_info);
if (device == NULL) {
return;
}
property_set_bool (device_info, device, property_name, property_index, enabled);
try {
XCloseDevice (QX11Info::display(), device);
} catch (int x) {
qWarning("%s:error",__func__);
2020-04-17 16:11:58 +08:00
}
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetDisableWTypingLibinput (bool state)
2020-03-19 18:59:01 +08:00
{
2020-08-25 19:07:22 +08:00
XDeviceInfo *device_info = nullptr;
2020-04-17 16:11:58 +08:00
int n_devices;
int i;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
/* This is only called once for synaptics but for libinput
* we need to loop through the list of devices
*/
device_info = XListInputDevices (QX11Info::display(), &n_devices);
2020-08-25 19:07:22 +08:00
if(!device_info){
qWarning("SetDisableWTypingLibinput: device_info is null");
2020-08-25 19:07:22 +08:00
return;
}
2020-04-17 16:11:58 +08:00
for (i = 0; i < n_devices; i++) {
touchpad_set_bool (&device_info[i], "libinput Disable While Typing Enabled", 0, state);
}
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
if (device_info != NULL)
XFreeDeviceList (device_info);
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetDisableWTyping (bool state)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
if (property_from_name ("Synaptics Off"))
SetDisableWTypingSynaptics (state);
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
if (property_from_name ("libinput Disable While Typing Enabled"))
SetDisableWTypingLibinput (state);
2020-03-19 18:59:01 +08:00
}
2020-07-23 09:33:02 +08:00
static void
set_tap_to_click_libinput (XDeviceInfo *device_info, bool state)
{
touchpad_set_bool (device_info, "libinput Tapping Enabled", 0, state);
}
static void
set_tap_to_click(XDeviceInfo *device_info, bool state, bool left_handed,
2020-07-23 09:33:02 +08:00
int one_finger_tap, int two_finger_tap, int three_finger_tap)
{
if (query_device_had_property(device_info,"Synaptics Tap Action")) {
set_tap_to_click_synaptics (device_info, state, 0,
one_finger_tap, two_finger_tap, three_finger_tap);
USD_LOG_SHOW_PARAM1(left_handed);
USD_LOG(LOG_DEBUG,"device name:%s",device_info->name);
}
2020-07-23 09:33:02 +08:00
if (property_from_name ("libinput Tapping Enabled"))
set_tap_to_click_libinput (device_info, state);
}
void MouseManager::SetTapToClickAll ()
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
int numdevices, i;
XDeviceInfo *devicelist = XListInputDevices (QX11Info::display(), &numdevices);
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
if (devicelist == NULL)
return;
2020-03-19 18:59:01 +08:00
bool state = settings_touchpad->get(KEY_TOUCHPAD_TAP_TO_CLICK).toBool();
bool left_handed = GetTouchpadHandedness (settings_mouse->get(KEY_LEFT_HANDED).toBool());
int one_finger_tap = settings_touchpad->get(KEY_TOUCHPAD_ONE_FINGER_TAP).toInt();
int two_finger_tap = settings_touchpad->get(KEY_TOUCHPAD_TWO_FINGER_TAP).toInt();
int three_finger_tap = settings_touchpad->get(KEY_TOUCHPAD_THREE_FINGER_TAP).toInt();
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
for (i = 0; i < numdevices; i++) {
set_tap_to_click(&devicelist[i], state, left_handed, one_finger_tap, two_finger_tap, three_finger_tap);
2020-04-17 16:11:58 +08:00
}
XFreeDeviceList (devicelist);
2020-03-19 18:59:01 +08:00
}
static void set_scrolling_synaptics (XDeviceInfo *device_info,
2020-04-03 20:38:30 +08:00
QGSettings *settings)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
touchpad_set_bool (device_info, "Synaptics Edge Scrolling", 0, settings->get(KEY_VERT_EDGE_SCROLL).toBool());
touchpad_set_bool (device_info, "Synaptics Edge Scrolling", 1, settings->get(KEY_HORIZ_EDGE_SCROLL).toBool());
touchpad_set_bool (device_info, "Synaptics Two-Finger Scrolling", 0, settings->get(KEY_VERT_TWO_FINGER_SCROLL).toBool());
touchpad_set_bool (device_info, "Synaptics Two-Finger Scrolling", 1, settings->get(KEY_HORIZ_TWO_FINGER_SCROLL).toBool());
2020-03-19 18:59:01 +08:00
}
static void set_scrolling_libinput (XDeviceInfo *device_info,
2020-04-03 20:38:30 +08:00
QGSettings *settings)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
XDevice *device;
int format, rc;
unsigned long nitems, bytes_after;
unsigned char *data;
Atom prop, type;
bool want_edge, want_2fg;
bool want_horiz;
//Display *display = QX11Info::display();
Display * display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
2020-04-17 16:11:58 +08:00
prop = property_from_name ("libinput Scroll Method Enabled");
if (!prop)
return;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
device = device_is_touchpad (device_info);
if (device == NULL) {
return;
}
want_2fg = settings->get(KEY_VERT_TWO_FINGER_SCROLL).toBool();
want_edge = settings->get(KEY_VERT_EDGE_SCROLL).toBool();
/* libinput only allows for one scroll method at a time.
* If both are set, pick 2fg scrolling.
*/
if (want_2fg)
want_edge = false;
USD_LOG(LOG_DEBUG,"setting scroll method on %s", device_info->name);
2020-04-17 16:11:58 +08:00
try {
rc = XGetDeviceProperty (display, device, prop, 0, 2,
False, XA_INTEGER, &type, &format, &nitems,
&bytes_after, &data);
if (rc == Success && type == XA_INTEGER && format == 8 && nitems >= 3) {
data[0] = want_2fg;
data[1] = want_edge;
XChangeDeviceProperty (display, device,
prop, XA_INTEGER, 8, PropModeReplace, data, nitems);
2020-03-19 18:59:01 +08:00
}
2020-04-17 16:11:58 +08:00
if (rc == Success)
XFree (data);
XCloseDevice (display, device);
} catch (int x) {
USD_LOG(LOG_DEBUG,"Error in setting scroll method on \"%s\"", device_info->name);
2020-04-17 16:11:58 +08:00
}
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
/* Horizontal scrolling is handled by xf86-input-libinput and
* there's only one bool. Pick the one matching the scroll method
* we picked above.
*/
if (want_2fg)
want_horiz = settings->get(KEY_HORIZ_TWO_FINGER_SCROLL).toBool();
else if (want_edge)
want_horiz = settings->get(KEY_HORIZ_EDGE_SCROLL).toBool();
else
return;
touchpad_set_bool (device_info, "libinput Horizontal Scroll Enabled", 0, want_horiz);
2020-03-19 18:59:01 +08:00
}
static void set_scrolling (XDeviceInfo *device_info,
2020-04-03 20:38:30 +08:00
QGSettings *settings)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
if (property_from_name ("Synaptics Edge Scrolling"))
set_scrolling_synaptics (device_info, settings);
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
if (property_from_name ("libinput Scroll Method Enabled"))
set_scrolling_libinput (device_info, settings);
2020-03-19 18:59:01 +08:00
}
void SetScrollingAll (QGSettings *settings)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
int numdevices, i;
XDeviceInfo *devicelist = XListInputDevices (QX11Info::display(), &numdevices);
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
if (devicelist == NULL)
return;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
for (i = 0; i < numdevices; i++) {
set_scrolling (&devicelist[i], settings);
}
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
XFreeDeviceList (devicelist);
2020-03-19 18:59:01 +08:00
}
void set_natural_scroll_synaptics (XDeviceInfo *device_info,
2020-04-03 20:38:30 +08:00
bool natural_scroll)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
XDevice *device;
int format, rc;
unsigned long nitems, bytes_after;
unsigned char* data;
long *ptr;
Atom prop, type;
Display * display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
// Display *display = QX11Info::display();
2020-04-17 16:11:58 +08:00
prop = property_from_name ("Synaptics Scrolling Distance");
if (!prop)
return;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
device = device_is_touchpad (device_info);
if (device == NULL) {
return;
}
qDebug ("Trying to set %s for \"%s\"",
natural_scroll ? "natural (reverse) scroll" : "normal scroll",
device_info->name);
try {
rc = XGetDeviceProperty (display , device, prop, 0, 2,
False, XA_INTEGER, &type, &format, &nitems,
&bytes_after, &data);
if (rc == Success && type == XA_INTEGER && format == 32 && nitems >= 2) {
ptr = (glong *) data;
if (natural_scroll) {
ptr[0] = -abs(ptr[0]);
ptr[1] = -abs(ptr[1]);
} else {
ptr[0] = abs(ptr[0]);
ptr[1] = abs(ptr[1]);
}
XChangeDeviceProperty (display, device, prop,
XA_INTEGER, 32, PropModeReplace, data, nitems);
2020-03-19 18:59:01 +08:00
}
2020-04-17 16:11:58 +08:00
if (rc == Success)
XFree (data);
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
XCloseDevice (display, device);
} catch (int x) {
qWarning("Error in setting natural scroll on \"%s\"", device_info->name);
2020-04-17 16:11:58 +08:00
}
2020-03-19 18:59:01 +08:00
}
void set_natural_scroll_libinput (XDeviceInfo *device_info,
2020-04-03 20:38:30 +08:00
bool natural_scroll)
2020-03-19 18:59:01 +08:00
{
2021-07-21 17:38:15 +08:00
USD_LOG (LOG_DEBUG,"Trying to set %s for \"%s\"",
2020-04-17 16:11:58 +08:00
natural_scroll ? "natural (reverse) scroll" : "normal scroll",
device_info->name);
touchpad_set_bool (device_info, "libinput Natural Scrolling Enabled",
0, natural_scroll);
2020-03-19 18:59:01 +08:00
}
void set_natural_scroll (XDeviceInfo *device_info,
2020-04-03 20:38:30 +08:00
bool natural_scroll)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
if (property_from_name ("Synaptics Scrolling Distance"))
set_natural_scroll_synaptics (device_info, natural_scroll);
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
if (property_from_name ("libinput Natural Scrolling Enabled"))
set_natural_scroll_libinput (device_info, natural_scroll);
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetNaturalScrollAll ()
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
int numdevices, i;
XDeviceInfo *devicelist = XListInputDevices (QX11Info::display(), &numdevices);
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
if (devicelist == NULL)
return;
bool natural_scroll = settings_touchpad->get(KEY_TOUCHPAD_NATURAL_SCROLL).toBool();
2020-04-17 16:11:58 +08:00
for (i = 0; i < numdevices; i++) {
set_natural_scroll (&devicelist[i], natural_scroll);
}
XFreeDeviceList (devicelist);
2020-03-19 18:59:01 +08:00
}
void set_touchpad_enabled (XDeviceInfo *device_info,
2020-04-17 16:11:58 +08:00
bool state)
2020-03-19 18:59:01 +08:00
{
2021-11-16 18:43:17 +08:00
Display* display = gdk_x11_get_default_xdisplay ();
XDevice * device;
2020-04-17 16:11:58 +08:00
device = device_is_touchpad (device_info);
if (device == NULL) {
return;
}
2021-11-16 18:43:17 +08:00
int realformat;
unsigned long nitems, bytes_after;
unsigned char *data;
Atom realtype, prop;
prop = XInternAtom (display, "Device Enabled", False);
if (!prop) {
return;
2020-04-17 16:11:58 +08:00
}
2020-04-19 14:44:51 +08:00
2021-11-16 18:43:17 +08:00
if (XGetDeviceProperty (display, device, prop, 0, 1, False,
XA_INTEGER, &realtype, &realformat, &nitems,
&bytes_after, &data) == Success) {
if (nitems == 1){
data[0] = state ? 1 : 0;
XChangeDeviceProperty(display, device, prop, XA_INTEGER, realformat, PropModeReplace, data, nitems);
}
XFree(data);
}
XCloseDevice (display, device);
2020-03-19 18:59:01 +08:00
}
void SetTouchpadEnabledAll (bool state)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
int numdevices, i;
XDeviceInfo *devicelist = XListInputDevices ( QX11Info::display(), &numdevices);
if (devicelist == NULL)
return;
for (i = 0; i < numdevices; i++) {
set_touchpad_enabled (&devicelist[i], state);
}
XFreeDeviceList (devicelist);
2020-03-19 18:59:01 +08:00
}
bool SetDisbleTouchpad(XDeviceInfo *device_info,
QGSettings *settings)
{
QString name;
bool state;
name = device_info->name;
bool PReceiver = name.contains("Receiver", Qt::CaseInsensitive);
bool PWireless = name.contains("Wireless", Qt::CaseInsensitive);
bool Pmouse = name.contains("Mouse", Qt::CaseInsensitive);
bool Pusb = name.contains("USB", Qt::CaseInsensitive);
if(Pmouse && ( PWireless || PReceiver || Pusb )) {
state = settings->get(KEY_TOUCHPAD_DISBLE_O_E_MOUSE).toBool();
if(state){//如果开启插入鼠标禁用触摸板,则直接修改触摸板状态
SetTouchpadEnabledAll(!state);
return true;
} else {//如果没有开启插入鼠标禁用触摸板,则根据触摸板总开关的状态,设置触摸板的enable状态
SetTouchpadEnabledAll(settings->get(KEY_TOUCHPAD_ENABLED).toBool());
}
}
return false;
}
2021-10-28 15:33:12 +08:00
bool checkMouseExists()
{
int numdevices, i;
XDeviceInfo *devicelist = XListInputDevices (QX11Info::display(), &numdevices);
if (devicelist == NULL){
return false;
}
for (i = 0; i < numdevices; i++) {
QString name;
name = devicelist[i].name;
bool PReceiver = name.contains("Receiver", Qt::CaseInsensitive);
bool PWireless = name.contains("Wireless", Qt::CaseInsensitive);
2021-10-28 15:33:12 +08:00
bool Pmouse = name.contains("Mouse", Qt::CaseInsensitive);
bool Pusb = name.contains("USB", Qt::CaseInsensitive);
if(Pmouse && ( PWireless || PReceiver || Pusb )) {
2021-10-28 15:33:12 +08:00
return true;
}
}
XFreeDeviceList (devicelist);
return false;
}
// while remove mouse
void SetPlugRemoveMouseEnableTouchpad(QGSettings *settings)
{
if(UsdBaseClass::isTablet()){
if(settings->get(KEY_TOUCHPAD_ENABLED).toBool()) {
SetTouchpadEnabledAll(settings->get(KEY_TOUCHPAD_ENABLED).toBool());
}
} else {
if(!checkMouseExists()) {
SetTouchpadEnabledAll(settings->get(KEY_TOUCHPAD_ENABLED).toBool());
}
}
}
void SetPlugMouseDisbleTouchpad(QGSettings *settings)
{
int numdevices, i;
XDeviceInfo *devicelist = XListInputDevices (QX11Info::display(), &numdevices);
2021-10-28 15:33:12 +08:00
if (devicelist == NULL) {
return;
}
for (i = 0; i < numdevices; i++) {
2021-10-28 15:33:12 +08:00
if(SetDisbleTouchpad (&devicelist[i], settings)) {
break;
}
}
XFreeDeviceList (devicelist);
}
void SetTouchpadDoubleClick(XDeviceInfo *device_info, bool state)
{
XDevice *device;
int format, rc;
unsigned long nitems, bytes_after;
unsigned char* data;
Atom prop, type;
Display * display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
// Display *display = gdk_x11_get_default_xdisplay ();//QX11Info::display();
prop = property_from_name ("Synaptics Gestures");
if (!prop)
return;
device = device_is_touchpad (device_info);
if (device == NULL) {
return;
}
qDebug ("Trying to set for \"%s\"", device_info->name);
try {
rc = XGetDeviceProperty (display , device, prop, 0, 1,
False, XA_INTEGER, &type, &format, &nitems,
&bytes_after, &data);
if (rc == Success && type == XA_INTEGER && format == 8 && nitems >= 1) {
if(state)
data[0]=1;
else
data[0]=0;
XChangeDeviceProperty (display, device, prop,
XA_INTEGER, 8, PropModeReplace, data, nitems);
}
if (rc == Success)
XFree (data);
XCloseDevice (display, device);
} catch (int x) {
qWarning("Error in setting natural scroll on \"%s\"", device_info->name);
}
}
void SetTouchpadDoubleClickAll(bool state)
{
int numdevices, i;
XDeviceInfo *devicelist = XListInputDevices (QX11Info::display(), &numdevices);
if (devicelist == NULL)
return;
for (i = 0; i < numdevices; i++) {
SetTouchpadDoubleClick (&devicelist[i], state);
}
XFreeDeviceList (devicelist);
}
//设置关闭右下角菜单
void MouseManager::SetBottomRightClickMenu(XDeviceInfo *device_info, bool state)
{
XDevice *device;
int format, rc;
unsigned long nitems, bytes_after;
unsigned char* data;
long *ptr;
Atom prop, type;
Display * display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
// Display *display = gdk_x11_get_default_xdisplay ();//QX11Info::display();
prop = property_from_name ("Synaptics Soft Button Areas");
if (!prop)
return;
device = device_is_touchpad (device_info);
if (device == NULL) {
return;
}
qDebug ("Trying to set for \"%s\"", device_info->name);
try {
rc = XGetDeviceProperty (display , device, prop, 0, 8,
False, XA_INTEGER, &type, &format, &nitems,
&bytes_after, &data);
if (rc == Success && type == XA_INTEGER && format == 32 && nitems >= 3) {
ptr = (long *)data;
if(ptr[0] != 0){
mAreaLeft = ptr[0];
mAreaTop = ptr[2];
}
if (state) {
ptr[0] = mAreaLeft;
ptr[2] = mAreaTop;
} else {
ptr[0] = 0;
ptr[2] = 0;
}
XChangeDeviceProperty (display, device, prop,
XA_INTEGER, 32, PropModeReplace, data, nitems);
}
if (rc == Success)
XFree (data);
XCloseDevice (display, device);
} catch (int x) {
qWarning("Error in setting natural scroll on \"%s\"", device_info->name);
}
}
void MouseManager::SetBottomRightConrnerClickMenu(bool state)
{
int numdevices, i;
XDeviceInfo *devicelist = XListInputDevices (QX11Info::display(), &numdevices);
if (devicelist == NULL)
return;
for (i = 0; i < numdevices; i++) {
SetBottomRightClickMenu(&devicelist[i], state);
}
XFreeDeviceList (devicelist);
}
2020-08-05 17:07:24 +08:00
void MouseManager::TouchpadCallback (QString keys)
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
if (keys.compare(QString::fromLocal8Bit(KEY_TOUCHPAD_DISABLE_W_TYPING))==0) {
SetDisableWTyping (settings_touchpad->get(keys).toBool()); //设置打字时禁用触摸板
2020-04-17 16:11:58 +08:00
} else if (keys.compare(QString::fromLocal8Bit(KEY_LEFT_HANDED))== 0) {
bool mouse_left_handed = settings_mouse->get(keys).toBool();
bool touchpad_left_handed = GetTouchpadHandedness (mouse_left_handed);
SetLeftHandedAll (mouse_left_handed, touchpad_left_handed); //设置左右手
2020-04-17 16:11:58 +08:00
} else if ((keys.compare(QString::fromLocal8Bit(KEY_TOUCHPAD_TAP_TO_CLICK)) == 0)
|| (keys.compare(QString::fromLocal8Bit(KEY_TOUCHPAD_ONE_FINGER_TAP)) == 0)
|| (keys.compare(QString::fromLocal8Bit(KEY_TOUCHPAD_TWO_FINGER_TAP)) == 0)
|| (keys.compare(QString::fromLocal8Bit(KEY_TOUCHPAD_THREE_FINGER_TAP))== 0)) {
SetTapToClickAll (); //设置多指手势
2020-04-17 16:11:58 +08:00
} else if ((keys.compare(QString::fromLocal8Bit(KEY_VERT_EDGE_SCROLL)) == 0)
|| (keys.compare(QString::fromLocal8Bit(KEY_HORIZ_EDGE_SCROLL)) == 0)
|| (keys.compare(QString::fromLocal8Bit(KEY_VERT_TWO_FINGER_SCROLL)) == 0)
|| (keys.compare(QString::fromLocal8Bit(KEY_HORIZ_TWO_FINGER_SCROLL)) == 0)) {
SetScrollingAll (settings_touchpad); //设置滚动
2020-04-17 16:11:58 +08:00
} else if (keys.compare(QString::fromLocal8Bit(KEY_TOUCHPAD_NATURAL_SCROLL)) == 0) {
SetNaturalScrollAll (); //设置上移下滚或上移上滚
USD_LOG(LOG_DEBUG,"set %s",KEY_TOUCHPAD_NATURAL_SCROLL);
2020-04-17 16:11:58 +08:00
} else if (keys.compare(QString::fromLocal8Bit(KEY_TOUCHPAD_ENABLED)) == 0) {
SetTouchpadEnabledAll (settings_touchpad->get(keys).toBool());//设置触摸板开关
} else if ((keys.compare((KEY_MOTION_ACCELERATION)) == 0)
|| (keys.compare((KEY_MOTION_THRESHOLD)) == 0)) {
SetMotionAll (); //设置鼠标速度
}else if (0 == QString::compare(keys, QString(KEY_MOTION_ACCELERATION), Qt::CaseInsensitive)||
0 == QString::compare(keys, QString(KEY_MOTION_THRESHOLD), Qt::CaseInsensitive)){
SetMotionAll (); //设置鼠标速度
}else if (keys == "motion-acceleration" || keys==KEY_MOTION_THRESHOLD){
}else if (keys.compare(QString::fromLocal8Bit(KEY_TOUCHPAD_DISBLE_O_E_MOUSE)) == 0) {
SetPlugMouseDisbleTouchpad(settings_touchpad); //设置插入鼠标时禁用触摸板
} else if (keys.compare(QString::fromLocal8Bit(KEY_TOUCHPAD_DOUBLE_CLICK_DRAG)) == 0){
SetTouchpadDoubleClickAll(settings_touchpad->get(KEY_TOUCHPAD_DOUBLE_CLICK_DRAG).toBool());//设置轻点击两次拖动打开关闭
} else if (keys.compare(QString::fromLocal8Bit(KEY_TOUCHPAD_BOTTOM_R_C_CLICK_M)) == 0){
SetBottomRightConrnerClickMenu(settings_touchpad->get(KEY_TOUCHPAD_BOTTOM_R_C_CLICK_M).toBool());//打开关闭右下角点击弹出菜单
} else if (keys.compare(QString::fromLocal8Bit(KEY_TOUCHPAD_MOUSE_SENSITVITY)) == 0){
} else {
USD_LOG(LOG_DEBUG,"keys:is skip..k%s", keys.toLatin1().data(),keys.toLatin1().data());
2020-04-17 16:11:58 +08:00
}
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetMouseSettings ()
2020-03-19 18:59:01 +08:00
{
bool mouse_left_handed = settings_mouse->get(KEY_LEFT_HANDED).toBool();
bool touchpad_left_handed = GetTouchpadHandedness (mouse_left_handed);
2020-04-03 20:38:30 +08:00
SetLeftHandedAll (mouse_left_handed, touchpad_left_handed);
2020-03-19 18:59:01 +08:00
SetMotionAll ();
SetMiddleButtonAll (settings_mouse->get(KEY_MIDDLE_BUTTON_EMULATION).toBool());
2021-04-02 18:38:36 +08:00
SetMouseWheelSpeed (settings_mouse->get(KEY_MOUSE_WHEEL_SPEED).toInt());
2021-10-28 15:33:12 +08:00
SetPlugMouseDisbleTouchpad(settings_touchpad);
2021-04-02 18:38:36 +08:00
}
2020-03-19 18:59:01 +08:00
2021-04-02 18:38:36 +08:00
void MouseManager::SetTouchSettings ()
{
SetTapToClickAll ();
SetScrollingAll (settings_touchpad);
SetNaturalScrollAll ();
SetTouchpadEnabledAll (settings_touchpad->get(KEY_TOUCHPAD_ENABLED).toBool());
2021-10-28 15:33:12 +08:00
// SetPlugMouseDisbleTouchpad(settings_touchpad);
SetPlugRemoveMouseEnableTouchpad(settings_touchpad);
SetTouchpadDoubleClickAll(settings_touchpad->get(KEY_TOUCHPAD_DOUBLE_CLICK_DRAG).toBool());
SetBottomRightConrnerClickMenu(settings_touchpad->get(KEY_TOUCHPAD_BOTTOM_R_C_CLICK_M).toBool());
2020-03-19 18:59:01 +08:00
}
GdkFilterReturn devicepresence_filter (GdkXEvent *xevent,
GdkEvent *event,
gpointer data)
{
2020-04-17 16:11:58 +08:00
XEvent *xev = (XEvent *) xevent;
XEventClass class_presence;
int xi_presence;
MouseManager * manager = (MouseManager *) data;
2020-03-19 18:59:01 +08:00
2020-04-17 16:11:58 +08:00
DevicePresence (gdk_x11_get_default_xdisplay (), xi_presence, class_presence);
2021-11-22 15:30:58 +08:00
if (xev->type == xi_presence) {
2020-04-17 16:11:58 +08:00
XDevicePresenceNotifyEvent *dpn = (XDevicePresenceNotifyEvent *) xev;
2021-09-22 11:37:53 +08:00
if (dpn->devchange == DeviceEnabled) {
2021-11-09 14:24:42 +08:00
USD_LOG(LOG_DEBUG,"new add deviced ID : %d",dpn->deviceid);
2021-10-28 15:33:12 +08:00
manager->SetMouseSettings ();
} else if(dpn->devchange == DeviceRemoved) {
manager->SetTouchSettings();
2021-09-22 11:37:53 +08:00
}
2020-04-17 16:11:58 +08:00
}
return GDK_FILTER_CONTINUE;
2020-03-19 18:59:01 +08:00
}
void MouseManager::SetDevicepresenceHandler ()
2020-03-19 18:59:01 +08:00
{
2020-04-17 16:11:58 +08:00
Display *display;
XEventClass class_presence;
int xi_presence;
display = QX11Info::display();
2020-03-19 18:59:01 +08:00
2020-07-25 20:23:33 +08:00
gdk_x11_display_error_trap_push (gdk_display_get_default());
2020-04-17 16:11:58 +08:00
DevicePresence (display, xi_presence, class_presence);
XSelectExtensionEvent (display,
RootWindow (display, DefaultScreen (display)),
&class_presence, 1);
2020-03-19 18:59:01 +08:00
2020-07-25 20:23:33 +08:00
gdk_display_flush (gdk_display_get_default());
if (!gdk_x11_display_error_trap_pop (gdk_display_get_default()))
gdk_window_add_filter (NULL, devicepresence_filter,this);
2020-03-19 18:59:01 +08:00
}
2020-08-05 17:07:24 +08:00
void MouseManager::MouseManagerIdleCb()
2020-03-19 18:59:01 +08:00
{
2020-04-03 20:38:30 +08:00
time->stop();
2020-03-19 18:59:01 +08:00
// connect(settings_mouse, &QGSettings::changed, this, &MouseManager::MouseCallback);
2021-08-31 17:28:55 +08:00
// connect(settings_touchpad, &QGSettings::changed, this, &MouseManager::TouchpadCallback);
QObject::connect(settings_mouse,SIGNAL(changed(QString)), this,SLOT(MouseCallback(QString)));
QObject::connect(settings_touchpad,SIGNAL(changed(QString)),this,SLOT(TouchpadCallback(QString)));
2021-07-21 17:38:15 +08:00
2020-04-03 20:38:30 +08:00
syndaemon_spawned = FALSE;
SetDevicepresenceHandler ();
SetMouseSettings ();
2021-04-02 18:38:36 +08:00
SetTouchSettings ();
SetDisableWTyping (settings_touchpad->get(KEY_TOUCHPAD_DISABLE_W_TYPING).toBool());
SetLocatePointer (settings_mouse->get(KEY_MOUSE_LOCATE_POINTER).toBool());
2021-10-28 15:33:12 +08:00
if(checkMouseExists()){
SetPlugMouseDisbleTouchpad(settings_touchpad);
} else {
SetPlugRemoveMouseEnableTouchpad(settings_touchpad);
}
2020-03-19 18:59:01 +08:00
}