diff --git a/client.h b/client.h index a7b546a..ec760ec 100644 --- a/client.h +++ b/client.h @@ -215,8 +215,13 @@ client_min_size(Client *c, int *width, int *height) if (client_is_x11(c)) { struct wlr_xwayland_surface_size_hints *size_hints; size_hints = c->surface.xwayland->size_hints; - *width = size_hints->min_width; - *height = size_hints->min_height; + if (size_hints) { + *width = size_hints->min_width; + *height = size_hints->min_height; + } else { + *width = 0; + *height = 0; + } return; } #endif @@ -226,6 +231,13 @@ client_min_size(Client *c, int *width, int *height) *height = state->min_height; } +static inline Client * +client_from_wlr_surface(struct wlr_surface *surface) +{ + struct wlr_scene_node *n = surface->data; + return n ? n->data : NULL; +} + static inline Client * client_from_popup(struct wlr_xdg_popup *popup) { diff --git a/config.def.h b/config.def.h index 190b0da..4f131dd 100644 --- a/config.def.h +++ b/config.def.h @@ -49,7 +49,31 @@ static const int repeat_delay = 600; /* Trackpad */ static const int tap_to_click = 1; +static const int tap_and_drag = 1; +static const int drag_lock = 1; static const int natural_scrolling = 0; +static const int disable_while_typing = 1; +static const int left_handed = 0; +static const int middle_button_emulation = 0; +/* You can choose between: +LIBINPUT_CONFIG_SCROLL_NO_SCROLL +LIBINPUT_CONFIG_SCROLL_2FG +LIBINPUT_CONFIG_SCROLL_EDGE +LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN +*/ +static const enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG; +/* You can choose between: +LIBINPUT_CONFIG_SEND_EVENTS_ENABLED +LIBINPUT_CONFIG_SEND_EVENTS_DISABLED +LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE +*/ +static const uint32_t send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; +/* You can choose between: +LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT +LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE +*/ +static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE; +static const double accel_speed = 0.0; /* If you want to use the windows key change this to WLR_MODIFIER_LOGO */ #define MODKEY WLR_MODIFIER_ALT diff --git a/dwl.1 b/dwl.1 index f50602c..d958210 100644 --- a/dwl.1 +++ b/dwl.1 @@ -7,7 +7,7 @@ .Sh SYNOPSIS .Nm .Op Fl v -.Op Fl s Ar command +.Op Fl s Ar startup command .Sh DESCRIPTION .Nm is a Wayland compositor based on wlroots. diff --git a/dwl.c b/dwl.c index 8b7d87c..e0a9c53 100644 --- a/dwl.c +++ b/dwl.c @@ -115,6 +115,7 @@ typedef struct { #ifdef XWAYLAND struct wl_listener activate; struct wl_listener configure; + struct wl_listener set_hints; #endif int bw; unsigned int tags; @@ -439,6 +440,7 @@ static void activatex11(struct wl_listener *listener, void *data); static void configurex11(struct wl_listener *listener, void *data); static void createnotifyx11(struct wl_listener *listener, void *data); static Atom getatom(xcb_connection_t *xc, const char *name); +static void sethints(struct wl_listener *listener, void *data); static void xwaylandready(struct wl_listener *listener, void *data); static struct wl_listener new_xwayland_surface = {.notify = createnotifyx11}; static struct wl_listener xwayland_ready = {.notify = xwaylandready}; @@ -870,6 +872,8 @@ commitnotify(struct wl_listener *listener, void *data) /* mark a pending resize as completed */ if (c->resize && c->resize <= c->surface.xdg->current.configure_serial) c->resize = 0; + else if (c->resize) + c->resize = client_set_size(c, c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw); } void @@ -1067,17 +1071,36 @@ createpointer(struct wlr_input_device *device) struct libinput_device *libinput_device = (struct libinput_device*) wlr_libinput_get_device_handle(device); - if (tap_to_click && libinput_device_config_tap_get_finger_count(libinput_device)) - libinput_device_config_tap_set_enabled(libinput_device, LIBINPUT_CONFIG_TAP_ENABLED); + if (libinput_device_config_tap_get_finger_count(libinput_device)) { + libinput_device_config_tap_set_enabled(libinput_device, tap_to_click); + libinput_device_config_tap_set_drag_enabled(libinput_device, tap_and_drag); + libinput_device_config_tap_set_drag_lock_enabled(libinput_device, drag_lock); + } if (libinput_device_config_scroll_has_natural_scroll(libinput_device)) libinput_device_config_scroll_set_natural_scroll_enabled(libinput_device, natural_scrolling); + + if (libinput_device_config_dwt_is_available(libinput_device)) + libinput_device_config_dwt_set_enabled(libinput_device, disable_while_typing); + + if (libinput_device_config_left_handed_is_available(libinput_device)) + libinput_device_config_left_handed_set(libinput_device, left_handed); + + if (libinput_device_config_middle_emulation_is_available(libinput_device)) + libinput_device_config_middle_emulation_set_enabled(libinput_device, middle_button_emulation); + + if (libinput_device_config_scroll_get_methods(libinput_device) != LIBINPUT_CONFIG_SCROLL_NO_SCROLL) + libinput_device_config_scroll_set_method (libinput_device, scroll_method); + + if (libinput_device_config_send_events_get_modes(libinput_device)) + libinput_device_config_send_events_set_mode(libinput_device, send_events_mode); + + if (libinput_device_config_accel_is_available(libinput_device)) { + libinput_device_config_accel_set_profile(libinput_device, accel_profile); + libinput_device_config_accel_set_speed(libinput_device, accel_speed); + } } - /* We don't do anything special with pointers. All of our pointer handling - * is proxied through wlr_cursor. On another compositor, you might take this - * opportunity to do libinput configuration on the device to set - * acceleration, etc. */ wlr_cursor_attach_input_device(cursor, device); } @@ -1112,6 +1135,7 @@ destroylayersurfacenotify(struct wl_listener *listener, void *data) wl_list_remove(&layersurface->map.link); wl_list_remove(&layersurface->unmap.link); wl_list_remove(&layersurface->surface_commit.link); + wlr_scene_node_destroy(layersurface->scene); if (layersurface->layer_surface->output) { Monitor *m = layersurface->layer_surface->output->data; if (m) @@ -1134,6 +1158,7 @@ destroynotify(struct wl_listener *listener, void *data) #ifdef XWAYLAND if (c->type != XDGShell) { wl_list_remove(&c->configure.link); + wl_list_remove(&c->set_hints.link); wl_list_remove(&c->activate.link); } else #endif @@ -1208,8 +1233,7 @@ focusclient(Client *c, int lift) return; } else { Client *w; - struct wlr_scene_node *node = old->data; - if (old->role_data && (w = node->data)) + if (old->role_data && (w = client_from_wlr_surface(old))) for (i = 0; i < 4; i++) wlr_scene_rect_set_color(w->border[i], bordercolor); @@ -1481,10 +1505,12 @@ mapnotify(struct wl_listener *listener, void *data) /* Create scene tree for this client and its border */ c->scene = &wlr_scene_tree_create(layers[LyrTile])->node; - c->scene_surface = client_surface(c)->data = c->type == XDGShell + c->scene_surface = c->type == XDGShell ? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg) : wlr_scene_subsurface_tree_create(c->scene, client_surface(c)); - c->scene_surface->data = c; + if (client_surface(c)) + client_surface(c)->data = c->scene; + c->scene->data = c->scene_surface->data = c; if (client_is_unmanaged(c)) { client_get_geometry(c, &c->geom); @@ -1499,7 +1525,6 @@ mapnotify(struct wl_listener *listener, void *data) c->border[i] = wlr_scene_rect_create(c->scene, 0, 0, bordercolor); c->border[i]->node.data = c; wlr_scene_rect_set_color(c->border[i], bordercolor); - wlr_scene_node_lower_to_bottom(&c->border[i]->node); } /* Initialize client geometry with room for border */ @@ -2297,10 +2322,6 @@ static LayerSurface* layer_surface_from_wlr_layer_surface_v1( return layer_surface->data; } -static Client* client_from_wlr_surface(struct wlr_surface* surface) { - return wlr_xdg_surface_from_wlr_surface(surface)->data; -} - static void get_parent_and_output_box(struct wlr_surface *focused_surface, struct wlr_box *parent, struct wlr_box *output_box) { struct wlr_output *output; @@ -2915,7 +2936,8 @@ toggleview(const Arg *arg) void unmaplayersurface(LayerSurface *layersurface) { - layersurface->layer_surface->mapped = 0; + layersurface->layer_surface->mapped = (layersurface->mapped = 0); + wlr_scene_node_set_enabled(layersurface->scene, 0); if (layersurface->layer_surface->surface == seat->keyboard_state.focused_surface) focusclient(selclient(), 1); @@ -3004,11 +3026,7 @@ void urgent(struct wl_listener *listener, void *data) { struct wlr_xdg_activation_v1_request_activate_event *event = data; - Client *c; - - if (!wlr_surface_is_xdg_surface(event->surface)) - return; - c = wlr_xdg_surface_from_wlr_surface(event->surface)->data; + Client *c = client_from_wlr_surface(event->surface); if (c != selclient()) { c->isurgent = 1; printstatus(); @@ -3150,6 +3168,7 @@ createnotifyx11(struct wl_listener *listener, void *data) LISTEN(&xwayland_surface->events.request_activate, &c->activate, activatex11); LISTEN(&xwayland_surface->events.request_configure, &c->configure, configurex11); + LISTEN(&xwayland_surface->events.set_hints, &c->set_hints, sethints); LISTEN(&xwayland_surface->events.set_title, &c->set_title, updatetitle); LISTEN(&xwayland_surface->events.destroy, &c->destroy, destroynotify); LISTEN(&xwayland_surface->events.request_fullscreen, &c->fullscreen, @@ -3169,6 +3188,16 @@ getatom(xcb_connection_t *xc, const char *name) return atom; } +void +sethints(struct wl_listener *listener, void *data) +{ + Client *c = wl_container_of(listener, c, set_hints); + if (c != selclient()) { + c->isurgent = c->surface.xwayland->hints_urgency; + printstatus(); + } +} + void xwaylandready(struct wl_listener *listener, void *data) {