Skip to content

Commit

Permalink
#56 init of using POINTER when is NumberPad activated (not allowed wh…
Browse files Browse the repository at this point in the history
…en is done any touch and key is not release yet)
  • Loading branch information
ldrahnik committed Jan 16, 2023
1 parent a550896 commit f6e002f
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 51 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ If you find this project useful, do not forget to give it a [![GitHub stars](htt
- Disabling sys NumLock from e.g. external keyboard disables NumberPad as well
- Enabling sys NumLock do not activate NumberPad (can be enabled)
- Disabling NumberPad by default disable sys Numlock as well (can be disabled which is useful when is connected external keyboard)
- Supports pointer button clicks (areas are for left <= 35%, middle > 35% and < 60% and right > 65% of touchpad width) when is NumberPad activated (can be disabled), recommended area for executing clicks is bottom offset to avoid send NumberPad number or character together with click
- Driver supports pointer moving & pointer button clicks when is NumberPad activated (left, right, middle click), recommended area for executing clicks or start moving is bottom offset to avoid send NumberPad number or char together with click
- Repeating the key, when is held (disabled by default)
- Multitouch up to 5 fingers (disabled by default)
- Safe slide gestures against accidental touches by default (by default is multitouch disabled so is not allowed use more then only 1 finger at the same moment)
Expand Down Expand Up @@ -148,8 +148,8 @@ Example: If you want to set the size of top right icon to bigger and you have ch
| --------------------------------------------- | -------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Key layout** | |
| `keys` | Required | | map of keys as array of arrays, dimension has to be atleast array of len 1 inside array<br><br>everything else what is not an event except `None` is sent as unicode `<left_shift>+<left_ctrl>+<U>+<0-F>` (use apostrophes!, e.g. `"%"` in layouts `up5401ea, ux581l` or `"#"` in layout `gx701`)
| `keys_ignore_offset` | | `[]` | map of keys which should be touchable even on offset area<br><br>e.g. used in layout `gx551` with value `[0,0]` where is NumLock key on the top left and right icon as primary activation area for NumLock is not used |
| **Top left icon** | | | any function is disabled when is missing option `top_left_icon_height` or `top_left_icon_width` and icon has to be touchable (`0` dimensions) |
| `keys_ignore_offset` | | `[]` | map of keys which should be touchable even on offset area<br><br>e.g. used in layout `gx551` with value `[0,0]` where is NumLock key on the top left and right icon as primary activation area for NumLock is not used
**Top left icon** | | | any function is disabled when is missing option `top_left_icon_height` or `top_left_icon_width` and icon has to be touchable (`0` dimensions) |
| `top_left_icon_width` | | | width of the top left icon
| `top_left_icon_height` | | | height of the top left icon
| `top_left_icon_slide_func_keys` | | `[EV_KEY.KEY_CALC]` | array of `InputEvent`
Expand Down Expand Up @@ -190,7 +190,6 @@ top_left_icon_slide_func_activation_y_ratio = 0.2
default_backlight_level = 0x01
top_left_icon_brightness_func_disabled = 0
brightness = 0x46
enabled_pointer_buttons = 1
enabled = 1
```

Expand All @@ -207,7 +206,6 @@ enabled = 1
| `multitouch` | | `0` | up to quint tap when enabled<br><br>Example 1: can be enabled NumberPad when second finger is touched on touchpad somewhere as well;<br><br>Example 2: brightness can be changed during using NumberPad for calculating)
| `one_touch_key_rotation` | | `0` | possibility of altering multiple keys during one-touch
| `key_repetitions` | | `0` | possible to enable with value `1` hold key for repeated pressing key like on a physical keyboard
| `enabled_pointer_buttons` | | `1` | possible to disable pointer button clicks when is NumberPad activated with value `0`
| **Top left icon** | | | custom function is used when is NumberPad on/off and is first touched `top_left_icon` and finger is slid to center and untouched atleast after ratio of touchpad width > `top_left_icon_slide_func_activation_x_ratio` and height > `top_left_icon_slide_func_activation_y_ratio` and array `top_left_icon_custom_keys` is not empty<br><br>brightness function is used only when is NumberPad activated, `top_left_icon_brightness_function_disabled` is not `1`, array `backlight_levels` is not empty and works like endless loop of incrementing brightness in interval `top_left_icon_activation_time`
| `top_left_icon_activation_time` | | `1` [s] | amount of time for touch `top_left_icon`
| `top_left_icon_slide_func_activation_x_ratio` | | `0.3` (30%) | ratio of touchpad width of slide
Expand Down Expand Up @@ -277,4 +275,4 @@ sudo systemctl stop asus_touchpad_numpad.service

Do you think my effort put into open source is useful for you / others? Put start on the GitHub repository. Every star makes me proud. The same as any contribution. Would you like to reward me more? Now exists the way. You can invite me for a coffee! I really appreciate that!

[![BuyMeACoffee](https://img.shields.io/badge/Buy%20to%20maintainer%20a%20coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/ldrahnik)
[![BuyMeACoffee](https://img.shields.io/badge/Buy%20to%20maintainer%20a%20coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/ldrahnik)
135 changes: 90 additions & 45 deletions asus_touchpad.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,8 @@ def set_none_to_current_mt_slot():
abs_mt_slot_numpad_key[abs_mt_slot_value] = None
abs_mt_slot_x_values[abs_mt_slot_value] = 0
abs_mt_slot_y_values[abs_mt_slot_value] = 0
#abs_mt_slot_x_init_values[abs_mt_slot_value] = -1
#abs_mt_slot_y_init_values[abs_mt_slot_value] = -1


def pressed_touchpad_top_left_icon(e):
Expand Down Expand Up @@ -475,8 +477,6 @@ def activate_numpad():
config_set(CONFIG_ENABLED, True)

try:
d_t.grab()

subprocess.call("i2ctransfer -f -y " + device_id +
" w13@0x15 0x05 0x00 0x3d 0x03 0x06 0x00 0x07 0x00 0x0d 0x14 0x03 0x01 0xad", shell=True)
if default_backlight_level != "0x01":
Expand All @@ -491,7 +491,7 @@ def activate_numpad():
# (if exists)
# TODO: atm do not care what last value is now displayed and which one (nearest higher) should be next (default 0x01 means turn leds on with last used level of brightness)
brightness = -1
except (OSError, libevdev.device.DeviceGrabError):
except (OSError):
pass


Expand All @@ -504,10 +504,10 @@ def deactivate_numpad():
" w13@0x15 0x05 0x00 0x3d 0x03 0x06 0x00 0x07 0x00 0x0d 0x14 0x03 0x00 0xad"

try:
d_t.ungrab()
ungrab()
subprocess.call(numpad_cmd, shell=True)
brightness = 0
except (OSError, libevdev.device.DeviceGrabError):
except (OSError):
pass


Expand Down Expand Up @@ -665,6 +665,9 @@ def load_all_config_values():
abs_mt_slot_numpad_key = np.array([None, None, None, None, None], dtype=libevdev.const.EventCode)
abs_mt_slot_x_values = np.array([-1, -1, -1, -1, -1], int)
abs_mt_slot_y_values = np.array([-1, -1, -1, -1, -1], int)
#abs_mt_slot_x_init_values = np.array([-1, -1, -1, -1, -1], int)
#abs_mt_slot_y_init_values = np.array([-1, -1, -1, -1, -1], int)
abs_mt_slot_grab_status = np.array([-1, -1, -1, -1, -1], int)
# equal to multi finger maximum
support_for_maximum_abs_mt_slots: int = 1
unsupported_abs_mt_slot: bool = False
Expand Down Expand Up @@ -771,6 +774,7 @@ def get_events_for_unicode_string(string):


def pressed_numpad_key():
global abs_mt_slot_grab_status, abs_mt_slot_numpad_key, abs_mt_slot_value

log.info("Pressed numpad key")
log.info(abs_mt_slot_numpad_key[abs_mt_slot_value])
Expand All @@ -787,6 +791,7 @@ def pressed_numpad_key():
]

try:
grab()
udev.send_events(events)
except OSError as e:
log.warning("Cannot send press event, %s", e)
Expand All @@ -797,8 +802,45 @@ def replaced_numpad_key(touched_key_now):
pressed_numpad_key()


def unpressed_numpad_key(replaced_by_key=None):
def grab():
global d_t

try:
log.info("grab")
d_t.grab()
abs_mt_slot_grab_status[abs_mt_slot_value] = 1
except libevdev.device.DeviceGrabError as e:
log.error("Error of grabbing, %s", e)


def is_grabbed_more_than_one_time():
result = 0

for status in abs_mt_slot_grab_status:
if status:
result = 1

if result > 1:
return True
else:
return False


def ungrab():
global d_t, abs_mt_slot_grab_status

if not multitouch or not is_grabbed_more_than_one_time():
is_grabbed = abs_mt_slot_grab_status[abs_mt_slot_value]
if is_grabbed:
abs_mt_slot_grab_status[abs_mt_slot_value] = 0

try:
d_t.ungrab()
except libevdev.device.DeviceGrabError as e:
log.error("Error of grabbing during pressed key, %s", e)


def unpressed_numpad_key(replaced_by_key=None):

log.info("Unpressed numpad key")
log.info(abs_mt_slot_numpad_key[abs_mt_slot_value])
Expand All @@ -812,11 +854,11 @@ def unpressed_numpad_key(replaced_by_key=None):

try:
udev.send_events(events)
ungrab()

except OSError as e:
log.warning("Cannot send press event, %s", e)


if replaced_by_key:
abs_mt_slot_numpad_key[abs_mt_slot_value] = replaced_by_key
else:
Expand Down Expand Up @@ -1026,30 +1068,47 @@ def stop_top_left_right_icon_slide_gestures():
top_right_icon_touch_start_time = 0


def pressed_pointer_button(key, msc, value):

events = [
InputEvent(EV_MSC.MSC_SCAN, msc),
InputEvent(key, value),
InputEvent(EV_SYN.SYN_REPORT, 0)
]
#def pressed_pointer_button(key, msc, value):
#
# events = [
# InputEvent(EV_MSC.MSC_SCAN, msc),
# InputEvent(key, value),
# InputEvent(EV_SYN.SYN_REPORT, 0)
# ]

try:
udev.send_events(events)
except OSError as e:
log.error("Cannot send event, %s", e)
# try:
# udev.send_events(events)
# except OSError as e:
# log.error("Cannot send event, %s", e)

if value == 1:
abs_mt_slot_numpad_key[abs_mt_slot_value] = key
else:
abs_mt_slot_numpad_key[abs_mt_slot_value] = None
# if value == 1:
# abs_mt_slot_numpad_key[abs_mt_slot_value] = key
# else:
# abs_mt_slot_numpad_key[abs_mt_slot_value] = None


def is_key_pointer_button(key):
result = key == EV_KEY.BTN_LEFT or key == EV_KEY.BTN_RIGHT or key == EV_KEY.BTN_MIDDLE
return result


# def is_not_finger_moved_to_end_grab():
# global abs_mt_slot_x_init_values, abs_mt_slot_y_init_values, abs_mt_slot_x_values, abs_mt_slot_y_values
#
# # already ungrabbed (so nothing is changed)
# if not abs_mt_slot_grab_status[abs_mt_slot_value]:
# return
#
# if\
# abs_mt_slot_x_init_values[abs_mt_slot_value] > abs_mt_slot_x_values[abs_mt_slot_value] + 100 or\
# abs_mt_slot_x_init_values[abs_mt_slot_value] < abs_mt_slot_x_values[abs_mt_slot_value] + 100 or\
# abs_mt_slot_y_init_values[abs_mt_slot_value] > abs_mt_slot_y_values[abs_mt_slot_value] + 100 or\
# abs_mt_slot_y_init_values[abs_mt_slot_value] < abs_mt_slot_y_values[abs_mt_slot_value] + 100:
#
# log.info("grab is ended, finger was moved")
# ungrab()


def listen_touchpad_events():
global brightness, d_t, abs_mt_slot_value, abs_mt_slot, abs_mt_slot_numpad_key,\
abs_mt_slot_x_values, abs_mt_slot_y_values, support_for_maximum_abs_mt_slots,\
Expand All @@ -1062,32 +1121,11 @@ def listen_touchpad_events():

current_slot_x = abs_mt_slot_x_values[abs_mt_slot_value]
current_slot_y = abs_mt_slot_y_values[abs_mt_slot_value]
current_slot_key = abs_mt_slot_numpad_key[abs_mt_slot_value]

# POINTER_BUTTON handling starts
#
# can not be excluded situation
# when is send number or character together
# with POINTER_BUTTON because can be send in slot firstly!
#
# for each EV_KEY.BTN_LEFT, EV_KEY.BTN_RIGHT, EV_KEY.BTN_MIDDLE
# if is send always only BTN_LEFT
# supply touchpad driver role and divides by position between LEFT, MIDDLE, RIGHT
if is_key_pointer_button(e.code) and not enabled_pointer_buttons:
continue

if numlock:
if e.matches(EV_KEY.BTN_LEFT):
if(current_slot_x <= (maxx / 100) * 35):
pressed_pointer_button(EV_KEY.BTN_LEFT, 272, e.value)
elif(current_slot_x > (maxx / 100) * 35 and current_slot_x < (maxx / 100) * 65):
pressed_pointer_button(EV_KEY.BTN_MIDDLE, 274, e.value)
else:
pressed_pointer_button(EV_KEY.BTN_RIGHT, 273, e.value)
# POINTER_BUTTON handling ends
current_slot_key = abs_mt_slot_numpad_key[abs_mt_slot_value]

if is_key_pointer_button(current_slot_key):
#log.info("skipping because current slot is pointer button")
# #log.info("skipping because current slot is pointer button")
continue

if e.matches(EV_ABS.ABS_MT_SLOT):
Expand Down Expand Up @@ -1124,10 +1162,16 @@ def listen_touchpad_events():

if e.matches(EV_ABS.ABS_MT_POSITION_X):
abs_mt_slot_x_values[abs_mt_slot_value] = e.value
#if abs_mt_slot_x_init_values[abs_mt_slot_value] == -1:
# abs_mt_slot_x_init_values[abs_mt_slot_value] = e.value
#is_not_finger_moved_to_end_grab()
is_not_finger_moved_to_another_key()

if e.matches(EV_ABS.ABS_MT_POSITION_Y):
abs_mt_slot_y_values[abs_mt_slot_value] = e.value
#if abs_mt_slot_y_init_values[abs_mt_slot_value] == -1:
# abs_mt_slot_y_init_values[abs_mt_slot_value] = e.value
#is_not_finger_moved_to_end_grab()
is_not_finger_moved_to_another_key()

if e.matches(EV_ABS.ABS_MT_TRACKING_ID):
Expand Down Expand Up @@ -1172,6 +1216,7 @@ def listen_touchpad_events():
if (row < 0 or col < 0):
continue
else:
# offset area
continue

if abs_mt_slot_numpad_key[abs_mt_slot_value] == None and e.value == 0:
Expand Down

0 comments on commit f6e002f

Please sign in to comment.