fix mouse entered and exited event logic

This commit is contained in:
Felix Kratz 2022-06-07 15:56:35 +02:00
parent 3129a49cd6
commit 0892e1323e
9 changed files with 108 additions and 36 deletions

View file

@ -114,11 +114,13 @@ void bar_draw(struct bar* bar) {
for (int i = 0; i < g_bar_manager.bar_item_count; i++) {
struct bar_item* bar_item = g_bar_manager.bar_items[i];
if (bar_item->position == POSITION_POPUP) {
continue;
}
struct window* window = bar_item_get_window(bar_item, bar->adid);
if (!(bar_item->position == POSITION_POPUP))
bar_item_remove_associated_bar(bar_item, bar->adid);
bar_item_remove_associated_bar(bar_item, bar->adid);
if (!bar_draws_item(bar, bar_item)
|| (bar_item->type == BAR_COMPONENT_GROUP
@ -137,16 +139,14 @@ void bar_draw(struct bar* bar) {
if (bar_item->popup.drawing && bar->adid == g_bar_manager.active_adid)
popup_draw(&bar_item->popup);
// SLSMoveWindow(g_connection, window->id, &window->origin);
if (!window_apply_frame(window) && !bar_item->needs_update) continue;
if (bar_item->update_mask & UPDATE_MOUSE_ENTERED
|| bar_item->update_mask & UPDATE_MOUSE_EXITED) {
// CGRect tracking_rect = window->frame;
// tracking_rect.origin = window->origin;
//
// SLSRemoveAllTrackingAreas(g_connection, window->id);
// SLSAddTrackingRect(g_connection, window->id, tracking_rect);
CGRect tracking_rect = window->frame;
SLSRemoveAllTrackingAreas(g_connection, window->id);
SLSAddTrackingRect(g_connection, window->id, tracking_rect);
}
CGContextClearRect(window->context, window->frame);
@ -295,6 +295,8 @@ void bar_resize(struct bar* bar) {
if (bar->hidden) return;
window_set_frame(&bar->window, bar_get_frame(bar));
window_apply_frame(&bar->window);
SLSRemoveAllTrackingAreas(g_connection, bar->window.id);
SLSAddTrackingRect(g_connection, bar->window.id, bar->window.frame);
bar_calculate_bounds(bar);
bar->needs_update = true;
bar_draw(bar);
@ -309,6 +311,8 @@ void bar_set_hidden(struct bar* bar, bool hidden) {
void bar_create_window(struct bar* bar) {
window_create(&bar->window, bar_get_frame(bar));
SLSRemoveAllTrackingAreas(g_connection, bar->window.id);
SLSAddTrackingRect(g_connection, bar->window.id, bar->window.frame);
window_set_level(&bar->window, g_bar_manager.window_level);
window_set_blur_radius(&bar->window, g_bar_manager.blur_radius);
if (!g_bar_manager.shadow) window_disable_shadow(&bar->window);

View file

@ -568,7 +568,7 @@ void bar_item_destroy(struct bar_item* bar_item) {
popup_destroy(&bar_item->popup);
background_destroy(&bar_item->background);
for (int j = 1; j < bar_item->num_windows; j++) {
for (int j = 1; j <= bar_item->num_windows; j++) {
bar_item_remove_window(bar_item, j);
}
if (bar_item->windows) free(bar_item->windows);

View file

@ -483,6 +483,32 @@ struct bar_item* bar_manager_get_item_by_point(struct bar_manager* bar_manager,
return NULL;
}
struct bar_item* bar_manager_get_item_by_wid(struct bar_manager* bar_manager, uint32_t wid, uint32_t adid) {
for (int i = 0; i < bar_manager->bar_item_count; i++) {
struct bar_item* bar_item = bar_manager->bar_items[i];
if (!bar_item->drawing || bar_item->num_windows < adid
|| bar_item->windows[adid - 1] == NULL) {
continue;
}
struct window* window = bar_item_get_window(bar_item, adid);
if (window->id == wid) {
return bar_item;
}
}
return NULL;
}
struct bar* bar_manager_get_bar_by_wid(struct bar_manager* bar_manager, uint32_t wid) {
for (int i = 0; i < bar_manager->bar_count; i++) {
if (bar_manager->bars[i]->window.id == wid) {
return bar_manager->bars[i];
}
}
return NULL;
}
void bar_manager_custom_events_trigger(struct bar_manager* bar_manager, char* name, struct env_vars* env_vars) {
uint64_t flag = custom_events_get_flag_for_name(&bar_manager->custom_events,
name );
@ -512,9 +538,13 @@ void bar_manager_handle_mouse_entered(struct bar_manager* bar_manager, struct ba
bar_item_mouse_entered(bar_item);
}
void bar_manager_handle_mouse_exited(struct bar_manager* bar_manager) {
for (int i = 0; i < bar_manager->bar_item_count; i++)
bar_item_mouse_exited(bar_manager->bar_items[i]);
void bar_manager_handle_mouse_exited(struct bar_manager* bar_manager, struct bar_item* bar_item) {
if (!bar_item) {
for (int i = 0; i < bar_manager->bar_item_count; i++)
bar_item_mouse_exited(bar_manager->bar_items[i]);
} else {
bar_item_mouse_exited(bar_item);
}
}
void bar_manager_handle_front_app_switch(struct bar_manager* bar_manager, char* info) {

View file

@ -69,6 +69,8 @@ bool bar_manager_set_notch_width(struct bar_manager* bar_manager, uint32_t width
void bar_manager_sort(struct bar_manager* bar_manager, struct bar_item** ordering, uint32_t count);
struct bar_item* bar_manager_get_item_by_point(struct bar_manager* bar_manager, CGPoint point, uint32_t adid);
struct bar_item* bar_manager_get_item_by_wid(struct bar_manager* bar_manager, uint32_t wid, uint32_t adid);
struct bar* bar_manager_get_bar_by_wid(struct bar_manager* bar_manager, uint32_t wid);
int bar_manager_get_item_index_for_name(struct bar_manager* bar_manager, char* name);
uint32_t bar_manager_length_for_bar_side(struct bar_manager* bar_manager, struct bar* bar, char side);
@ -80,7 +82,7 @@ void bar_manager_refresh(struct bar_manager* bar_manager, bool forced);
void bar_manager_resize(struct bar_manager* bar_manager);
void bar_manager_handle_mouse_entered(struct bar_manager* bar_manager, struct bar_item* bar_item);
void bar_manager_handle_mouse_exited(struct bar_manager* bar_manager);
void bar_manager_handle_mouse_exited(struct bar_manager* bar_manager, struct bar_item* bar_item);
void bar_manager_handle_front_app_switch(struct bar_manager* bar_manager, char* info);
void bar_manager_handle_space_change(struct bar_manager* bar_manager);
void bar_manager_handle_display_change(struct bar_manager* bar_manager);

View file

@ -113,20 +113,23 @@ EVENT_CALLBACK(EVENT_HANDLER_MACH_MESSAGE) {
EVENT_CALLBACK(EVENT_HANDLER_MOUSE_UP) {
debug("%s\n", __FUNCTION__);
CGPoint point = CGEventGetLocation(context);
debug("EVENT_HANDLER_MOUSE_UP\n");
uint32_t wid = get_window_id_from_cg_event(context);
CGEventType type = CGEventGetType(context);
uint32_t modifier_keys = CGEventGetFlags(context);
uint32_t adid = display_arrangement(display_active_display_id());
printf("EVENT_HANDLER_MOUSE_UP: D#%d (x: %.0f, y: %.0f) -> ",
adid,
point.x,
point.y );
struct bar_item* bar_item = bar_manager_get_item_by_point(&g_bar_manager,
point,
adid );
struct bar_item* bar_item = bar_manager_get_item_by_wid(&g_bar_manager,
wid,
adid );
if (!bar_item) {
CGPoint point = CGEventGetLocation(context);
bar_item = bar_manager_get_item_by_point(&g_bar_manager, point, adid);
}
printf("item: %s\n", bar_item ? bar_item->name : "NULL");
debug("item: %s\n", bar_item ? bar_item->name : "NULL");
bar_item_on_click(bar_item, type, modifier_keys);
CFRelease(context);
return EVENT_SUCCESS;
@ -134,18 +137,28 @@ EVENT_CALLBACK(EVENT_HANDLER_MOUSE_UP) {
EVENT_CALLBACK(EVENT_HANDLER_MOUSE_ENTERED) {
debug("%s\n", __FUNCTION__);
CGPoint point = CGEventGetLocation(context);
debug("EVENT_HANDLER_MOUSE_ENTERED\n");
uint32_t wid = get_window_id_from_cg_event(context);
uint32_t adid = display_arrangement(display_active_display_id());
printf("EVENT_HANDLER_MOUSE_ENTERED: D#%d (x: %.0f, y: %.0f) -> ",
adid,
point.x,
point.y );
struct bar_item* bar_item = bar_manager_get_item_by_point(&g_bar_manager,
point,
adid );
struct bar* bar = bar_manager_get_bar_by_wid(&g_bar_manager, wid);
if (bar) {
// Handle global mouse entered event
CFRelease(context);
return EVENT_SUCCESS;
}
printf("item: %s\n", bar_item ? bar_item->name : "NULL");
struct bar_item* bar_item = bar_manager_get_item_by_wid(&g_bar_manager,
wid,
adid );
if (!bar_item) {
CGPoint point = CGEventGetLocation(context);
bar_item = bar_manager_get_item_by_point(&g_bar_manager, point, adid);
}
debug("item: %s\n", bar_item ? bar_item->name : "NULL");
bar_manager_handle_mouse_entered(&g_bar_manager, bar_item);
CFRelease(context);
return EVENT_SUCCESS;
@ -153,8 +166,24 @@ EVENT_CALLBACK(EVENT_HANDLER_MOUSE_ENTERED) {
EVENT_CALLBACK(EVENT_HANDLER_MOUSE_EXITED) {
debug("%s\n", __FUNCTION__);
printf("EVENT_HANDLER_MOUSE_EXITED \n");
bar_manager_handle_mouse_exited(&g_bar_manager);
debug("EVENT_HANDLER_MOUSE_EXITED\n");
uint32_t adid = display_arrangement(display_active_display_id());
uint32_t wid = get_window_id_from_cg_event(context);
struct bar* bar = bar_manager_get_bar_by_wid(&g_bar_manager, wid);
if (bar) {
// Handle global mouse exited event
CFRelease(context);
return EVENT_SUCCESS;
}
struct bar_item* bar_item = bar_manager_get_item_by_wid(&g_bar_manager,
wid,
adid );
debug("item: %s\n", bar_item ? bar_item->name : "NULL");
bar_manager_handle_mouse_exited(&g_bar_manager, bar_item);
CFRelease(context);
return EVENT_SUCCESS;
}

View file

@ -8,7 +8,7 @@
struct event_loop;
extern OSStatus SLSFindWindowByGeometry(int cid, int zero, int one, int zero_again, CGPoint *screen_point, CGPoint *window_point, uint32_t *wid, int *wcid);
extern uint32_t get_window_id_from_cg_event(CGEventRef cgevent);
#define EVENT_CALLBACK(name) uint32_t name(void *context)
typedef EVENT_CALLBACK(event_callback);

View file

@ -70,8 +70,8 @@ void popup_calculate_bounds(struct popup* popup) {
uint32_t cell_height = max(bar_item_get_height(bar_item),
popup->cell_size );
uint32_t item_x = x + bar_item->background.padding_left;
uint32_t item_y = y + y + (popup->horizontal ? height : cell_height) / 2;
uint32_t item_x = max((int)x + bar_item->background.padding_left, 0);
uint32_t item_y = y + (popup->horizontal ? height : cell_height) / 2;
uint32_t item_height = popup->horizontal ? height : cell_height;
uint32_t item_width = bar_item->background.padding_right

View file

@ -14,3 +14,5 @@ void workspace_create_custom_observer (void **context, char* notification);
void workspace_event_handler_init(void **context);
void workspace_event_handler_begin(void **context);
void workspace_event_handler_end(void *context);
uint32_t get_window_id_from_cg_event(CGEventRef cgevent);

View file

@ -23,6 +23,11 @@ void workspace_create_custom_observer (void **context, char* notification) {
[ws_context addCustomObserver:@(notification)];
}
uint32_t get_window_id_from_cg_event(CGEventRef cgevent) {
NSEvent *nsEvent = [NSEvent eventWithCGEvent:cgevent];
return [nsEvent windowNumber];
}
@implementation workspace_context
- (id)init {
if ((self = [super init])) {