Skip to content

Commit

Permalink
popups are respected in global mouse entered and exited events
Browse files Browse the repository at this point in the history
  • Loading branch information
FelixKratz committed Jun 11, 2022
1 parent d0f29dc commit 20c3326
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 13 deletions.
66 changes: 65 additions & 1 deletion src/bar_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ struct bar_item* bar_manager_get_item_by_wid(struct bar_manager* bar_manager, ui
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) {
|| !bar_item->windows[adid - 1]) {
continue;
}

Expand All @@ -515,6 +515,70 @@ struct bar* bar_manager_get_bar_by_wid(struct bar_manager* bar_manager, uint32_t
return NULL;
}

bool bar_manager_mouse_over_any_bar(struct bar_manager* bar_manager) {
for (int i = 0; i < bar_manager->bar_count; i++) {
if (bar_manager->bars[i]->mouse_over) return true;
}
return false;
}

struct popup* bar_manager_get_popup_by_wid(struct bar_manager* bar_manager, uint32_t wid) {
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->popup.drawing) {
continue;
}

struct window* window = &bar_item->popup.window;

if (window->id == wid) {
return &bar_item->popup;
}
}
return NULL;
}

struct popup* bar_manager_get_popup_by_point(struct bar_manager* bar_manager, CGPoint point) {
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->popup.drawing) {
continue;
}

struct window* window = &bar_item->popup.window;

CGRect frame = window->frame;
frame.origin = window->origin;

if (CGRectContainsPoint(frame, point)) return &bar_item->popup;
}
return NULL;

}

struct bar* bar_manager_get_bar_by_point(struct bar_manager* bar_manager, CGPoint point) {
for (int i = 0; i < bar_manager->bar_count; i++) {
struct window* window = &bar_manager->bars[i]->window;

CGRect frame = window->frame;
frame.origin = window->origin;

if (CGRectContainsPoint(frame, point)) return bar_manager->bars[i];
}
return NULL;
}

bool bar_manager_mouse_over_any_popup(struct bar_manager* bar_manager) {
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->popup.drawing) {
continue;
}
if (bar_item->popup.mouse_over) return true;
}
return false;
}

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 );
Expand Down
5 changes: 5 additions & 0 deletions src/bar_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,15 @@ 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* bar_manager_get_bar_by_point(struct bar_manager* bar_manager, CGPoint point);
struct popup* bar_manager_get_popup_by_point(struct bar_manager* bar_manager, CGPoint point);
struct bar_item* bar_manager_get_item_by_wid(struct bar_manager* bar_manager, uint32_t wid, uint32_t adid);
struct popup* bar_manager_get_popup_by_wid(struct bar_manager* bar_manager, uint32_t wid);
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);
bool bar_manager_mouse_over_any_popup(struct bar_manager* bar_manager);
bool bar_manager_mouse_over_any_bar(struct bar_manager* bar_manager);

void bar_manager_freeze(struct bar_manager* bar_manager);
void bar_manager_unfreeze(struct bar_manager* bar_manager);
Expand Down
2 changes: 2 additions & 0 deletions src/custom_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#define UPDATE_MOUSE_EXITED 1ULL << 5
#define UPDATE_MOUSE_CLICKED 1ULL << 6
#define UPDATE_SYSTEM_WILL_SLEEP 1ULL << 7
#define UPDATE_ENTERED_GLOBAL 1ULL << 8
#define UPDATE_EXITED_GLOBAL 1ULL << 9

extern void* g_workspace_context;
extern void workspace_create_custom_observer(void** context, char* name);
Expand Down
67 changes: 58 additions & 9 deletions src/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ EVENT_CALLBACK(EVENT_HANDLER_MOUSE_ENTERED) {
struct bar* bar = bar_manager_get_bar_by_wid(&g_bar_manager, wid);
if (bar) {
// Handle global mouse entered event
if (!bar->mouse_over) {
if (!bar->mouse_over
&& !bar_manager_mouse_over_any_popup(&g_bar_manager)) {
bar->mouse_over = true;
bar_manager_handle_mouse_entered_global(&g_bar_manager);
}
Expand All @@ -154,9 +155,22 @@ EVENT_CALLBACK(EVENT_HANDLER_MOUSE_ENTERED) {
return EVENT_SUCCESS;
}

struct popup* popup = bar_manager_get_popup_by_wid(&g_bar_manager, wid);
if (popup) {
// Handle global mouse entered event
if (!popup->mouse_over
&& !bar_manager_mouse_over_any_bar(&g_bar_manager)) {
popup->mouse_over = true;
bar_manager_handle_mouse_entered_global(&g_bar_manager);
}

CFRelease(context);
return EVENT_SUCCESS;
}
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);
Expand All @@ -174,15 +188,44 @@ EVENT_CALLBACK(EVENT_HANDLER_MOUSE_EXITED) {
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) {
struct bar* bar,* bar_target;
struct popup* popup,* popup_target;
struct window* origin_window;
bool over_target = false;

CGPoint point = CGEventGetLocation(context);
if ((bar = bar_manager_get_bar_by_wid(&g_bar_manager, wid))) {
origin_window = &bar->window;
popup_target = bar_manager_get_popup_by_point(&g_bar_manager,
point );
over_target = (popup_target != NULL);
}
else if ((popup = bar_manager_get_popup_by_wid(&g_bar_manager, wid))) {
origin_window = &popup->window;
bar_target = bar_manager_get_bar_by_point(&g_bar_manager, point);
over_target = (bar_target != NULL);
}

if (bar || popup) {
// Handle global mouse exited event
CGPoint point = CGEventGetLocation(context);
CGRect frame = bar->window.frame;
frame.origin = bar->window.origin;
if (!CGRectContainsPoint(frame, point)) {
bar->mouse_over = false;
CGRect frame = origin_window->frame;
frame.origin = origin_window->origin;

bool over_origin = CGRectContainsPoint(frame, point);

if (!over_origin && !over_target) {
if (bar) bar->mouse_over = false;
else popup->mouse_over = false;
bar_manager_handle_mouse_exited_global(&g_bar_manager);
} else if (!over_origin && over_target) {
if (bar) {
bar->mouse_over = false;
popup_target->mouse_over = true;
}
else {
popup->mouse_over = false;
bar_target->mouse_over = true;
}
}

CFRelease(context);
Expand All @@ -193,8 +236,14 @@ EVENT_CALLBACK(EVENT_HANDLER_MOUSE_EXITED) {
wid,
adid );

if (!bar_item || !(bar_item->update_mask & UPDATE_EXITED_GLOBAL)
|| bar_manager_get_bar_by_point(&g_bar_manager, point)) {
bar_manager_handle_mouse_exited(&g_bar_manager, bar_item);
} else if (bar_item) {
bar_item->mouse_over = false;
}

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;
}
6 changes: 5 additions & 1 deletion src/popup.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
void popup_init(struct popup* popup) {
popup->drawing = false;
popup->horizontal = false;
popup->mouse_over = false;
popup->overrides_cell_size = false;
popup->anchor = (CGPoint){0, 0};
popup->y_offset = 0;
Expand Down Expand Up @@ -180,6 +181,8 @@ void popup_draw(struct popup* popup) {
SLSOrderWindow(g_connection, popup->window.id, -1, 0);
window_set_frame(&popup->window, popup_get_frame(popup));
window_apply_frame(&popup->window);
SLSRemoveAllTrackingAreas(g_connection, popup->window.id);
SLSAddTrackingRect(g_connection, popup->window.id, popup->window.frame);

CGContextClearRect(popup->window.context, popup->background.bounds);

Expand All @@ -197,7 +200,8 @@ void popup_draw(struct popup* popup) {
popup->background.bounds.size.height / 2. );

tracking_rect.origin.y -= tracking_rect.size.height;
SLSAddTrackingRect(g_connection, popup->window.id, tracking_rect);
// TODO: Fix tracking rects in popups
// SLSAddTrackingRect(g_connection, popup->window.id, tracking_rect);
}

bar_item_set_bounding_rect_for_display(bar_item,
Expand Down
1 change: 1 addition & 0 deletions src/popup.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ struct popup {
bool drawing;
bool horizontal;
bool overrides_cell_size;
bool mouse_over;

char align;

Expand Down
5 changes: 4 additions & 1 deletion src/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ void window_create(struct window* window, CGRect frame) {

frame.origin = (CGPoint){0, 0};
CFTypeRef frame_region = window_create_region(window, frame);
uint64_t id;
SLSNewWindow(g_connection, 2, window->origin.x, window->origin.y,
frame_region,
&window->id );
&id );

window->id = (uint32_t)id;

CFRelease(frame_region);

Expand Down
2 changes: 1 addition & 1 deletion src/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct window {
bool needs_move;
bool needs_resize;

uint64_t id;
uint32_t id;
uint32_t surface_id;

CGRect frame;
Expand Down

0 comments on commit 20c3326

Please sign in to comment.