mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-02-27 01:40:22 -05:00
fix: popup position constrain not work for some app
This commit is contained in:
parent
a28647585f
commit
564df864bf
4 changed files with 118 additions and 47 deletions
|
|
@ -3647,13 +3647,13 @@ void reapply_cursor_style(void) {
|
|||
|
||||
cursor_mgr = wlr_xcursor_manager_create(config.cursor_theme, cursor_size);
|
||||
|
||||
if(cursor_size > 0){
|
||||
char size_str[16];
|
||||
snprintf(size_str, sizeof(size_str), "%d", cursor_size);
|
||||
if (cursor_size > 0) {
|
||||
char size_str[16];
|
||||
snprintf(size_str, sizeof(size_str), "%d", cursor_size);
|
||||
setenv("XCURSOR_SIZE", size_str, 1);
|
||||
}
|
||||
|
||||
if(config.cursor_theme){
|
||||
if (config.cursor_theme) {
|
||||
setenv("XCURSOR_THEME", config.cursor_theme, 1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,15 +77,6 @@ Monitor *output_from_wlr_output(struct wlr_output *wlr_output) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Monitor *output_nearest_to(int32_t lx, int32_t ly) {
|
||||
double closest_x, closest_y;
|
||||
wlr_output_layout_closest_point(output_layout, NULL, lx, ly, &closest_x,
|
||||
&closest_y);
|
||||
|
||||
return output_from_wlr_output(
|
||||
wlr_output_layout_output_at(output_layout, closest_x, closest_y));
|
||||
}
|
||||
|
||||
bool output_is_usable(Monitor *m) { return m && m->wlr_output->enabled; }
|
||||
|
||||
static bool
|
||||
|
|
@ -255,7 +246,7 @@ static void update_popup_position(struct dwl_input_method_popup *popup) {
|
|||
cursor_rect = (struct wlr_box){0};
|
||||
}
|
||||
|
||||
output = output_nearest_to(cursor_rect.x, cursor_rect.y);
|
||||
output = get_monitor_nearest_to(cursor_rect.x, cursor_rect.y);
|
||||
if (!output_is_usable(output)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,3 +96,12 @@ Monitor *xytomon(double x, double y) {
|
|||
struct wlr_output *o = wlr_output_layout_output_at(output_layout, x, y);
|
||||
return o ? o->data : NULL;
|
||||
}
|
||||
|
||||
Monitor *get_monitor_nearest_to(int32_t lx, int32_t ly) {
|
||||
double closest_x, closest_y;
|
||||
wlr_output_layout_closest_point(output_layout, NULL, lx, ly, &closest_x,
|
||||
&closest_y);
|
||||
|
||||
return output_from_wlr_output(
|
||||
wlr_output_layout_output_at(output_layout, closest_x, closest_y));
|
||||
}
|
||||
137
src/mango.c
137
src/mango.c
|
|
@ -486,6 +486,16 @@ typedef struct {
|
|||
bool being_unmapped;
|
||||
} LayerSurface;
|
||||
|
||||
typedef struct {
|
||||
struct wlr_xdg_popup *wlr_popup;
|
||||
Client *client;
|
||||
LayerSurface *layer;
|
||||
uint32_t type;
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener commit;
|
||||
struct wl_listener reposition;
|
||||
} Popup;
|
||||
|
||||
typedef struct {
|
||||
const char *symbol;
|
||||
void (*arrange)(Monitor *);
|
||||
|
|
@ -790,6 +800,7 @@ static Client *get_focused_stack_client(Client *sc);
|
|||
static bool client_is_in_same_stack(Client *sc, Client *tc, Client *fc);
|
||||
static void monitor_stop_skip_frame_timer(Monitor *m);
|
||||
static int monitor_skip_frame_timeout_callback(void *data);
|
||||
static Monitor *get_monitor_nearest_to(int32_t lx, int32_t ly);
|
||||
|
||||
#include "data/static_keymap.h"
|
||||
#include "dispatch/bind_declare.h"
|
||||
|
|
@ -895,11 +906,8 @@ static KeyMode keymode = {
|
|||
.isdefault = true,
|
||||
};
|
||||
|
||||
static char *env_vars[] = {"DISPLAY",
|
||||
"WAYLAND_DISPLAY",
|
||||
"XDG_CURRENT_DESKTOP",
|
||||
"XDG_SESSION_TYPE",
|
||||
NULL};
|
||||
static char *env_vars[] = {"DISPLAY", "WAYLAND_DISPLAY", "XDG_CURRENT_DESKTOP",
|
||||
"XDG_SESSION_TYPE", NULL};
|
||||
static struct {
|
||||
enum wp_cursor_shape_device_v1_shape shape;
|
||||
struct wlr_surface *surface;
|
||||
|
|
@ -2545,37 +2553,107 @@ void destroydecoration(struct wl_listener *listener, void *data) {
|
|||
wl_list_remove(&c->set_decoration_mode.link);
|
||||
}
|
||||
|
||||
void commitpopup(struct wl_listener *listener, void *data) {
|
||||
static void popup_unconstrain(Popup *popup) {
|
||||
struct wlr_xdg_popup *wlr_popup = popup->wlr_popup;
|
||||
|
||||
if (!wlr_popup || !wlr_popup->parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_scene_node *parent_node = wlr_popup->parent->data;
|
||||
if (!parent_node) {
|
||||
wlr_log(WLR_ERROR, "Popup parent has no scene node");
|
||||
return;
|
||||
}
|
||||
int parent_lx, parent_ly;
|
||||
wlr_scene_node_coords(parent_node, &parent_lx, &parent_ly);
|
||||
|
||||
struct wlr_box *scheduled = &wlr_popup->scheduled.geometry;
|
||||
int popup_lx = parent_lx + scheduled->x;
|
||||
int popup_ly = parent_ly + scheduled->y;
|
||||
|
||||
Monitor *mon = get_monitor_nearest_to(popup_lx, popup_ly);
|
||||
|
||||
struct wlr_box usable = popup->type == LayerShell ? mon->m : mon->w;
|
||||
|
||||
struct wlr_box constraint_box = {
|
||||
.x = usable.x - parent_lx,
|
||||
.y = usable.y - parent_ly,
|
||||
.width = usable.width,
|
||||
.height = usable.height,
|
||||
};
|
||||
|
||||
wlr_xdg_popup_unconstrain_from_box(wlr_popup, &constraint_box);
|
||||
}
|
||||
|
||||
static void destroypopup(struct wl_listener *listener, void *data) {
|
||||
Popup *popup = wl_container_of(listener, popup, destroy);
|
||||
wl_list_remove(&popup->destroy.link);
|
||||
wl_list_remove(&popup->reposition.link);
|
||||
free(popup);
|
||||
}
|
||||
|
||||
static void commitpopup(struct wl_listener *listener, void *data) {
|
||||
Popup *popup = wl_container_of(listener, popup, commit);
|
||||
|
||||
struct wlr_surface *surface = data;
|
||||
struct wlr_xdg_popup *popup = wlr_xdg_popup_try_from_wlr_surface(surface);
|
||||
LayerSurface *l = NULL;
|
||||
struct wlr_xdg_popup *wkr_popup =
|
||||
wlr_xdg_popup_try_from_wlr_surface(surface);
|
||||
|
||||
Client *c = NULL;
|
||||
struct wlr_box box;
|
||||
LayerSurface *l = NULL;
|
||||
int32_t type = -1;
|
||||
|
||||
if (!popup || !popup->base->initial_commit)
|
||||
if (!wkr_popup || !wkr_popup->base->initial_commit)
|
||||
goto commitpopup_listen_free;
|
||||
|
||||
type = toplevel_from_wlr_surface(popup->base->surface, &c, &l);
|
||||
if (!popup->parent || !popup->parent->data || type < 0)
|
||||
goto commitpopup_listen_free;
|
||||
|
||||
wlr_scene_node_raise_to_top(popup->parent->data);
|
||||
|
||||
popup->base->surface->data =
|
||||
wlr_scene_xdg_surface_create(popup->parent->data, popup->base);
|
||||
if ((l && !l->mon) || (c && !c->mon)) {
|
||||
wlr_xdg_popup_destroy(popup);
|
||||
type = toplevel_from_wlr_surface(wkr_popup->base->surface, &c, &l);
|
||||
if (!wkr_popup->parent || !wkr_popup->parent->data || type < 0) {
|
||||
wlr_xdg_popup_destroy(wkr_popup);
|
||||
goto commitpopup_listen_free;
|
||||
}
|
||||
box = type == LayerShell ? l->mon->m : c->mon->w;
|
||||
box.x -= (type == LayerShell ? l->scene->node.x : c->geom.x);
|
||||
box.y -= (type == LayerShell ? l->scene->node.y : c->geom.y);
|
||||
wlr_xdg_popup_unconstrain_from_box(popup, &box);
|
||||
|
||||
wlr_scene_node_raise_to_top(wkr_popup->parent->data);
|
||||
|
||||
wkr_popup->base->surface->data =
|
||||
wlr_scene_xdg_surface_create(wkr_popup->parent->data, wkr_popup->base);
|
||||
if ((l && !l->mon) || (c && !c->mon)) {
|
||||
wlr_xdg_popup_destroy(wkr_popup);
|
||||
goto commitpopup_listen_free;
|
||||
}
|
||||
|
||||
popup->client = c;
|
||||
popup->layer = l;
|
||||
popup->type = type;
|
||||
popup->wlr_popup = wkr_popup;
|
||||
|
||||
popup_unconstrain(popup);
|
||||
|
||||
commitpopup_listen_free:
|
||||
wl_list_remove(&listener->link);
|
||||
free(listener);
|
||||
wl_list_remove(&popup->commit.link);
|
||||
popup->commit.notify = NULL;
|
||||
}
|
||||
|
||||
static void repositionpopup(struct wl_listener *listener, void *data) {
|
||||
Popup *popup = wl_container_of(listener, popup, reposition);
|
||||
popup_unconstrain(popup);
|
||||
}
|
||||
|
||||
static void createpopup(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xdg_popup *wlr_popup = data;
|
||||
|
||||
Popup *popup = calloc(1, sizeof(Popup));
|
||||
if (!popup)
|
||||
return;
|
||||
|
||||
popup->destroy.notify = destroypopup;
|
||||
wl_signal_add(&wlr_popup->events.destroy, &popup->destroy);
|
||||
|
||||
popup->commit.notify = commitpopup;
|
||||
wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit);
|
||||
|
||||
popup->reposition.notify = repositionpopup;
|
||||
wl_signal_add(&wlr_popup->events.reposition, &popup->reposition);
|
||||
}
|
||||
|
||||
void createdecoration(struct wl_listener *listener, void *data) {
|
||||
|
|
@ -3165,13 +3243,6 @@ void createpointerconstraint(struct wl_listener *listener, void *data) {
|
|||
&pointer_constraint->destroy, destroypointerconstraint);
|
||||
}
|
||||
|
||||
void createpopup(struct wl_listener *listener, void *data) {
|
||||
/* This event is raised when a client (either xdg-shell or layer-shell)
|
||||
* creates a new popup. */
|
||||
struct wlr_xdg_popup *popup = data;
|
||||
LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup);
|
||||
}
|
||||
|
||||
void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint) {
|
||||
if (active_constraint == constraint)
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue