mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-05-03 06:46:38 -04:00
feat: use keyboard group and support select close animaiton type
This commit is contained in:
parent
8b8437fd3c
commit
e1cf7db447
6 changed files with 856 additions and 767 deletions
348
IM.h
348
IM.h
|
|
@ -1,7 +1,11 @@
|
||||||
#ifdef IM
|
#ifdef IM
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <wlr/types/wlr_input_method_v2.h>
|
|
||||||
#include <wlr/types/wlr_text_input_v3.h>
|
#include <wlr/types/wlr_text_input_v3.h>
|
||||||
|
#include <wlr/types/wlr_input_method_v2.h>
|
||||||
|
|
||||||
|
#ifdef HANDWRITE
|
||||||
|
#include <handwrite-unstable-v1-protocol.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The relay structure manages the relationship between text-input and
|
* The relay structure manages the relationship between text-input and
|
||||||
|
|
@ -53,6 +57,7 @@ struct dwl_text_input {
|
||||||
struct wl_listener text_input_destroy;
|
struct wl_listener text_input_destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct dwl_input_popup {
|
struct dwl_input_popup {
|
||||||
struct dwl_input_method_relay *relay;
|
struct dwl_input_method_relay *relay;
|
||||||
struct wlr_input_popup_surface_v2 *popup_surface;
|
struct wlr_input_popup_surface_v2 *popup_surface;
|
||||||
|
|
@ -65,6 +70,7 @@ struct dwl_input_popup {
|
||||||
int x, y;
|
int x, y;
|
||||||
bool visible;
|
bool visible;
|
||||||
|
|
||||||
|
|
||||||
struct wl_listener popup_map;
|
struct wl_listener popup_map;
|
||||||
struct wl_listener popup_unmap;
|
struct wl_listener popup_unmap;
|
||||||
struct wl_listener popup_destroy;
|
struct wl_listener popup_destroy;
|
||||||
|
|
@ -72,6 +78,7 @@ struct dwl_input_popup {
|
||||||
//struct wl_listener focused_surface_unmap;
|
//struct wl_listener focused_surface_unmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void dwl_input_method_relay_init(struct dwl_input_method_relay *relay);
|
void dwl_input_method_relay_init(struct dwl_input_method_relay *relay);
|
||||||
// Updates currently focused surface. Surface must belong to the same
|
// Updates currently focused surface. Surface must belong to the same
|
||||||
// seat.
|
// seat.
|
||||||
|
|
@ -82,74 +89,90 @@ static void handle_im_grab_keyboard(struct wl_listener *listener, void *data);
|
||||||
static void handle_im_keyboard_grab_destroy(struct wl_listener *listener,
|
static void handle_im_keyboard_grab_destroy(struct wl_listener *listener,
|
||||||
void *data);
|
void *data);
|
||||||
static void input_popup_update(struct dwl_input_popup *popup);
|
static void input_popup_update(struct dwl_input_popup *popup);
|
||||||
|
static struct dwl_text_input *relay_get_focused_text_input(struct dwl_input_method_relay *relay);
|
||||||
|
|
||||||
struct wlr_input_method_manager_v2 *input_method_manager;
|
struct wlr_input_method_manager_v2 *input_method_manager;
|
||||||
struct wlr_text_input_manager_v3 *text_input_manager;
|
struct wlr_text_input_manager_v3 *text_input_manager;
|
||||||
struct dwl_input_method_relay *input_relay;
|
struct dwl_input_method_relay *input_relay;
|
||||||
|
// static int NO_printstatus=0; // i suspect that printstatus will make dwl hang with fcitx5
|
||||||
|
|
||||||
|
#ifdef HANDWRITE
|
||||||
|
static void receive_handwrite_text_from_handwrite_input_app(struct wl_client *client, struct wl_resource *resource, const char *text){
|
||||||
|
struct dwl_text_input *text_input;
|
||||||
|
|
||||||
|
wlr_log(WLR_INFO,"receive_handwrite_text_from_handwrite_input_app called with:%s",text);
|
||||||
|
text_input = relay_get_focused_text_input(input_relay);
|
||||||
|
|
||||||
|
if (text_input){
|
||||||
|
wlr_log(WLR_INFO,"receive_handwrite_text_from_handwrite_input_app will commit %s",text);
|
||||||
|
wlr_text_input_v3_send_commit_string(text_input->input,text);
|
||||||
|
wlr_text_input_v3_send_done(text_input->input);
|
||||||
|
}else wlr_log(WLR_INFO, "no focused text_input for handwrite");
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct zwp_handwrite_v1_interface handwrite_interface_impl = {
|
||||||
|
.send_handwrite_text = receive_handwrite_text_from_handwrite_input_app,
|
||||||
|
};
|
||||||
|
|
||||||
|
// struct wl_client* handwrite_app=NULL;//TODO: multiple handwrite app instance?
|
||||||
|
// void zwp_handwrite_v1_handle_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id){
|
||||||
|
// wlr_log(WLR_INFO,"zwp_handwrite_v1_handle_bind called");
|
||||||
|
// handwrite_app = client;
|
||||||
|
// struct wl_resource *resource = wl_resource_create(client, &zwp_handwrite_v1_interface, zwp_handwrite_v1_interface.version, id);
|
||||||
|
// wl_resource_set_implementation(resource, &handwrite_interface_impl, NULL, NULL);
|
||||||
|
// }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get keyboard grab of the seat from sway_keyboard if we should forward events
|
* Get keyboard grab of the seat from sway_keyboard if we should forward events
|
||||||
* to it.
|
* to it.
|
||||||
*
|
*
|
||||||
* Returns NULL if the keyboard is not grabbed by an input method,
|
* Returns NULL if the keyboard is not grabbed by an input method,
|
||||||
* or if event is from virtual keyboard of the same client as grab.
|
* or if event is from virtual keyboard
|
||||||
* TODO: see https://github.com/swaywm/wlroots/issues/2322
|
|
||||||
*/
|
*/
|
||||||
static struct wlr_input_method_keyboard_grab_v2 *
|
static struct wlr_input_method_keyboard_grab_v2 *keyboard_get_im_grab(KeyboardGroup* kb) {
|
||||||
keyboard_get_im_grab(Keyboard *kb) {
|
|
||||||
struct wlr_input_method_v2 *input_method = input_relay->input_method;
|
struct wlr_input_method_v2 *input_method = input_relay->input_method;
|
||||||
struct wlr_virtual_keyboard_v1 *virtual_keyboard =
|
|
||||||
wlr_input_device_get_virtual_keyboard(&kb->wlr_keyboard->base);
|
|
||||||
if (!input_method || !input_method->keyboard_grab ||
|
|
||||||
(virtual_keyboard &&
|
|
||||||
wl_resource_get_client(virtual_keyboard->resource) ==
|
|
||||||
wl_resource_get_client(input_method->keyboard_grab->resource))) {
|
|
||||||
if (!input_method){
|
if (!input_method){
|
||||||
wlr_log(WLR_DEBUG,
|
wlr_log(WLR_DEBUG, "keypress keyboard_get_im_grab return NULL:no input_method");
|
||||||
"keypress keyboard_get_im_grab return NULL:no input_method");
|
|
||||||
} else if (!input_method->keyboard_grab) {
|
|
||||||
wlr_log(WLR_DEBUG, "keypress keyboard_get_im_grab return NULL:no "
|
|
||||||
"input_method->keyboard_grab");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virtual_keyboard) {
|
|
||||||
wlr_log(WLR_DEBUG,
|
|
||||||
"keypress keyboard_get_im_grab return NULL:virtual_keyboard");
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
} else if (!input_method->keyboard_grab){
|
||||||
return input_method->keyboard_grab;
|
wlr_log(WLR_DEBUG, "keypress keyboard_get_im_grab return NULL:no input_method->keyboard_grab");
|
||||||
|
return NULL;
|
||||||
|
} else if (kb != kb_group) {
|
||||||
|
wlr_log(WLR_DEBUG, "keypress keyboard_get_im_grab return NULL:virtual_keyboard");
|
||||||
|
return NULL;
|
||||||
|
} else return input_method->keyboard_grab;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_im_grab_keyboard(struct wl_listener *listener, void *data) {
|
static void handle_im_grab_keyboard(struct wl_listener *listener, void *data) {
|
||||||
struct dwl_input_method_relay *relay =
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
wl_container_of(listener, relay, input_method_grab_keyboard);
|
input_method_grab_keyboard);
|
||||||
// wl_container_of 宏的第二个参数sample,
|
//wl_container_of 宏的第二个参数sample, 这里是relay,无须是已经初始化的变量,只要是返回值类型的变量就可以了,这里就是dwl_input_method_relay类型的变量
|
||||||
// 这里是relay,无须是已经初始化的变量,只要是返回值类型的变量就可以了,这里就是dwl_input_method_relay类型的变量
|
|
||||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
|
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
|
||||||
|
|
||||||
// send modifier state to grab
|
// send modifier state to grab
|
||||||
struct wlr_keyboard *active_keyboard = wlr_seat_get_keyboard(seat);
|
struct wlr_keyboard *active_keyboard = wlr_seat_get_keyboard(seat);
|
||||||
if (active_keyboard){
|
if (active_keyboard){
|
||||||
wlr_log(WLR_INFO,"im_grab_keyboard");
|
wlr_log(WLR_INFO,"im_grab_keyboard");
|
||||||
wlr_input_method_keyboard_grab_v2_set_keyboard(keyboard_grab,
|
wlr_input_method_keyboard_grab_v2_set_keyboard(keyboard_grab,active_keyboard);
|
||||||
active_keyboard);
|
wlr_input_method_keyboard_grab_v2_send_modifiers(keyboard_grab, &active_keyboard->modifiers);
|
||||||
wlr_input_method_keyboard_grab_v2_send_modifiers(
|
}
|
||||||
keyboard_grab, &active_keyboard->modifiers);
|
else
|
||||||
} else
|
|
||||||
wlr_log(WLR_INFO,"im_grab_keyboard but no active keyboard");
|
wlr_log(WLR_INFO,"im_grab_keyboard but no active keyboard");
|
||||||
|
|
||||||
|
|
||||||
wl_signal_add(&keyboard_grab->events.destroy,
|
wl_signal_add(&keyboard_grab->events.destroy,
|
||||||
&relay->input_method_keyboard_grab_destroy);
|
&relay->input_method_keyboard_grab_destroy);
|
||||||
relay->input_method_keyboard_grab_destroy.notify =
|
relay->input_method_keyboard_grab_destroy.notify =
|
||||||
handle_im_keyboard_grab_destroy;
|
handle_im_keyboard_grab_destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_im_keyboard_grab_destroy(struct wl_listener *listener,
|
static void handle_im_keyboard_grab_destroy(struct wl_listener *listener, void *data) {
|
||||||
void *data) {
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
struct dwl_input_method_relay *relay =
|
input_method_keyboard_grab_destroy);
|
||||||
wl_container_of(listener, relay, input_method_keyboard_grab_destroy);
|
|
||||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
|
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
|
||||||
wlr_log(WLR_DEBUG,"im_keyboard_grab_destroy");
|
wlr_log(WLR_DEBUG,"im_keyboard_grab_destroy");
|
||||||
wl_list_remove(&relay->input_method_keyboard_grab_destroy.link);
|
wl_list_remove(&relay->input_method_keyboard_grab_destroy.link);
|
||||||
|
|
@ -160,8 +183,9 @@ static void handle_im_keyboard_grab_destroy(struct wl_listener *listener,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dwl_text_input *
|
|
||||||
relay_get_focusable_text_input(struct dwl_input_method_relay *relay) {
|
static struct dwl_text_input *relay_get_focusable_text_input(
|
||||||
|
struct dwl_input_method_relay *relay) {
|
||||||
struct dwl_text_input *text_input = NULL;
|
struct dwl_text_input *text_input = NULL;
|
||||||
wl_list_for_each(text_input, &relay->text_inputs, link) {
|
wl_list_for_each(text_input, &relay->text_inputs, link) {
|
||||||
if (text_input->pending_focused_surface) {
|
if (text_input->pending_focused_surface) {
|
||||||
|
|
@ -171,8 +195,8 @@ relay_get_focusable_text_input(struct dwl_input_method_relay *relay) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dwl_text_input *
|
static struct dwl_text_input *relay_get_focused_text_input(
|
||||||
relay_get_focused_text_input(struct dwl_input_method_relay *relay) {
|
struct dwl_input_method_relay *relay) {
|
||||||
struct dwl_text_input *text_input = NULL;
|
struct dwl_text_input *text_input = NULL;
|
||||||
wl_list_for_each(text_input, &relay->text_inputs, link) {
|
wl_list_for_each(text_input, &relay->text_inputs, link) {
|
||||||
if (text_input->input->focused_surface) {
|
if (text_input->input->focused_surface) {
|
||||||
|
|
@ -185,8 +209,8 @@ relay_get_focused_text_input(struct dwl_input_method_relay *relay) {
|
||||||
static void handle_im_commit(struct wl_listener *listener, void *data) {
|
static void handle_im_commit(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_input_method_v2 *context;
|
struct wlr_input_method_v2 *context;
|
||||||
|
|
||||||
struct dwl_input_method_relay *relay =
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
wl_container_of(listener, relay, input_method_commit);
|
input_method_commit);
|
||||||
|
|
||||||
struct dwl_text_input *text_input = relay_get_focused_text_input(relay);
|
struct dwl_text_input *text_input = relay_get_focused_text_input(relay);
|
||||||
if (!text_input) {
|
if (!text_input) {
|
||||||
|
|
@ -207,18 +231,17 @@ static void handle_im_commit(struct wl_listener *listener, void *data) {
|
||||||
context->current.commit_text);
|
context->current.commit_text);
|
||||||
wlr_log(WLR_DEBUG,"commit_text: %s", context->current.commit_text);
|
wlr_log(WLR_DEBUG,"commit_text: %s", context->current.commit_text);
|
||||||
}
|
}
|
||||||
if (context->current.delete.before_length ||
|
if (context->current.delete.before_length
|
||||||
context->current.delete.after_length) {
|
|| context->current.delete.after_length) {
|
||||||
wlr_text_input_v3_send_delete_surrounding_text(
|
wlr_text_input_v3_send_delete_surrounding_text(text_input->input,
|
||||||
text_input->input, context->current.delete.before_length,
|
context->current.delete.before_length,
|
||||||
context->current.delete.after_length);
|
context->current.delete.after_length);
|
||||||
}
|
}
|
||||||
wlr_text_input_v3_send_done(text_input->input);
|
wlr_text_input_v3_send_done(text_input->input);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void text_input_set_pending_focused_surface(
|
||||||
text_input_set_pending_focused_surface(struct dwl_text_input *text_input,
|
struct dwl_text_input *text_input, struct wlr_surface *surface) {
|
||||||
struct wlr_surface *surface) {
|
|
||||||
wl_list_remove(&text_input->pending_focused_surface_destroy.link);
|
wl_list_remove(&text_input->pending_focused_surface_destroy.link);
|
||||||
text_input->pending_focused_surface = surface;
|
text_input->pending_focused_surface = surface;
|
||||||
|
|
||||||
|
|
@ -233,15 +256,16 @@ text_input_set_pending_focused_surface(struct dwl_text_input *text_input,
|
||||||
static void handle_im_destroy(struct wl_listener *listener, void *data) {
|
static void handle_im_destroy(struct wl_listener *listener, void *data) {
|
||||||
struct dwl_text_input *text_input;
|
struct dwl_text_input *text_input;
|
||||||
|
|
||||||
struct dwl_input_method_relay *relay =
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
wl_container_of(listener, relay, input_method_destroy);
|
input_method_destroy);
|
||||||
struct wlr_input_method_v2 *context = data;
|
struct wlr_input_method_v2 *context = data;
|
||||||
wlr_log(WLR_INFO,"IM destroy");
|
wlr_log(WLR_INFO,"IM destroy");
|
||||||
assert(context == relay->input_method);
|
assert(context == relay->input_method);
|
||||||
|
|
||||||
wl_list_remove(&relay->input_method_commit.link);
|
wl_list_remove(&relay->input_method_commit.link);
|
||||||
wl_list_remove(&relay->input_method_grab_keyboard.link);
|
wl_list_remove(&relay->input_method_grab_keyboard.link);
|
||||||
wl_list_remove(&relay->input_method_destroy.link);
|
|
||||||
wl_list_remove(&relay->input_method_new_popup_surface.link);
|
wl_list_remove(&relay->input_method_new_popup_surface.link);
|
||||||
|
wl_list_remove(&relay->input_method_destroy.link);
|
||||||
|
|
||||||
relay->input_method = NULL;
|
relay->input_method = NULL;
|
||||||
|
|
||||||
|
|
@ -263,21 +287,20 @@ static void relay_send_im_state(struct dwl_input_method_relay *relay,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: only send each of those if they were modified
|
// TODO: only send each of those if they were modified
|
||||||
wlr_input_method_v2_send_surrounding_text(
|
wlr_input_method_v2_send_surrounding_text(input_method,
|
||||||
input_method, input->current.surrounding.text,
|
input->current.surrounding.text, input->current.surrounding.cursor,
|
||||||
input->current.surrounding.cursor, input->current.surrounding.anchor);
|
input->current.surrounding.anchor);
|
||||||
wlr_input_method_v2_send_text_change_cause(input_method,
|
wlr_input_method_v2_send_text_change_cause(input_method,
|
||||||
input->current.text_change_cause);
|
input->current.text_change_cause);
|
||||||
wlr_input_method_v2_send_content_type(input_method,
|
wlr_input_method_v2_send_content_type(input_method,
|
||||||
input->current.content_type.hint,
|
input->current.content_type.hint, input->current.content_type.purpose);
|
||||||
input->current.content_type.purpose);
|
|
||||||
wlr_input_method_v2_send_done(input_method);
|
wlr_input_method_v2_send_done(input_method);
|
||||||
// TODO: pass intent, display popup size
|
// TODO: pass intent, display popup size
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_text_input_enable(struct wl_listener *listener, void *data) {
|
static void handle_text_input_enable(struct wl_listener *listener, void *data) {
|
||||||
struct dwl_text_input *text_input =
|
struct dwl_text_input *text_input = wl_container_of(listener, text_input,
|
||||||
wl_container_of(listener, text_input, text_input_enable);
|
text_input_enable);
|
||||||
if (text_input->relay->input_method == NULL) {
|
if (text_input->relay->input_method == NULL) {
|
||||||
wlr_log(WLR_INFO, "text_input_enable but input method is NULL");
|
wlr_log(WLR_INFO, "text_input_enable but input method is NULL");
|
||||||
return;
|
return;
|
||||||
|
|
@ -294,16 +317,14 @@ static void handle_text_input_enable(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
/* static void handle_text_input_commit(struct wl_listener *listener, */
|
/* static void handle_text_input_commit(struct wl_listener *listener, */
|
||||||
/* void *data) { */
|
/* void *data) { */
|
||||||
/* struct dwl_text_input *text_input = wl_container_of(listener,
|
/* struct dwl_text_input *text_input = wl_container_of(listener, text_input, */
|
||||||
* text_input, */
|
|
||||||
/* text_input_commit); */
|
/* text_input_commit); */
|
||||||
/* if (!text_input->input->current_enabled) { */
|
/* if (!text_input->input->current_enabled) { */
|
||||||
/* wlr_log(WLR_INFO, "text_input_commit but not enabled"); */
|
/* wlr_log(WLR_INFO, "text_input_commit but not enabled"); */
|
||||||
/* return; */
|
/* return; */
|
||||||
/* } */
|
/* } */
|
||||||
/* if (text_input->relay->input_method == NULL) { */
|
/* if (text_input->relay->input_method == NULL) { */
|
||||||
/* wlr_log(WLR_INFO, "text_input_commit but input method is NULL");
|
/* wlr_log(WLR_INFO, "text_input_commit but input method is NULL"); */
|
||||||
*/
|
|
||||||
/* return; */
|
/* return; */
|
||||||
/* } */
|
/* } */
|
||||||
/* wlr_log(WLR_DEBUG, "text_input_commit"); */
|
/* wlr_log(WLR_DEBUG, "text_input_commit"); */
|
||||||
|
|
@ -323,20 +344,21 @@ static void relay_disable_text_input(struct dwl_input_method_relay *relay,
|
||||||
wlr_input_method_v2_send_deactivate(relay->input_method);
|
wlr_input_method_v2_send_deactivate(relay->input_method);
|
||||||
wlr_log(WLR_INFO,"input_method deactivate for xwayland");
|
wlr_log(WLR_INFO,"input_method deactivate for xwayland");
|
||||||
#endif
|
#endif
|
||||||
// but if you keep the line above while remove the line below, input Chinese
|
//but if you keep the line above while remove the line below, input Chinese in geogebra(xwayland) won't work
|
||||||
// in geogebra(xwayland) won't work
|
|
||||||
relay_send_im_state(relay, text_input->input);
|
relay_send_im_state(relay, text_input->input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void handle_text_input_destroy(struct wl_listener *listener,
|
static void handle_text_input_destroy(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct dwl_text_input *text_input =
|
struct dwl_text_input *text_input = wl_container_of(listener, text_input,
|
||||||
wl_container_of(listener, text_input, text_input_destroy);
|
text_input_destroy);
|
||||||
|
|
||||||
if (text_input->input->current_enabled) {
|
if (text_input->input->current_enabled) {
|
||||||
wlr_log(WLR_INFO,"text_input_destroy when still enabled");
|
wlr_log(WLR_INFO,"text_input_destroy when still enabled");
|
||||||
relay_disable_text_input(text_input->relay, text_input);
|
relay_disable_text_input(text_input->relay, text_input);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
wlr_log(WLR_INFO,"text_input_destroy");
|
wlr_log(WLR_INFO,"text_input_destroy");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -351,8 +373,8 @@ static void handle_text_input_destroy(struct wl_listener *listener,
|
||||||
|
|
||||||
static void handle_pending_focused_surface_destroy(struct wl_listener *listener,
|
static void handle_pending_focused_surface_destroy(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct dwl_text_input *text_input =
|
struct dwl_text_input *text_input = wl_container_of(listener, text_input,
|
||||||
wl_container_of(listener, text_input, pending_focused_surface_destroy);
|
pending_focused_surface_destroy);
|
||||||
struct wlr_surface *surface = data;
|
struct wlr_surface *surface = data;
|
||||||
assert(text_input->pending_focused_surface == surface);
|
assert(text_input->pending_focused_surface == surface);
|
||||||
text_input->pending_focused_surface = NULL;
|
text_input->pending_focused_surface = NULL;
|
||||||
|
|
@ -360,10 +382,11 @@ static void handle_pending_focused_surface_destroy(struct wl_listener *listener,
|
||||||
wl_list_init(&text_input->pending_focused_surface_destroy.link);
|
wl_list_init(&text_input->pending_focused_surface_destroy.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void relay_handle_text_input_new(struct wl_listener *listener,
|
static void relay_handle_text_input_new(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct dwl_input_method_relay *relay =
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
wl_container_of(listener, relay, text_input_new);
|
text_input_new);
|
||||||
struct wlr_text_input_v3 *wlr_text_input = data;
|
struct wlr_text_input_v3 *wlr_text_input = data;
|
||||||
if (seat != wlr_text_input->seat) {
|
if (seat != wlr_text_input->seat) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -398,22 +421,20 @@ static void relay_handle_text_input_new(struct wl_listener *listener,
|
||||||
wl_list_init(&input->pending_focused_surface_destroy.link);
|
wl_list_init(&input->pending_focused_surface_destroy.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static LayerSurface* layer_surface_from_wlr_layer_surface_v1(
|
static LayerSurface* layer_surface_from_wlr_layer_surface_v1(
|
||||||
struct wlr_layer_surface_v1* layer_surface) {
|
struct wlr_layer_surface_v1* layer_surface) {
|
||||||
return layer_surface->data;
|
return layer_surface->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void get_parent_and_output_box(struct wlr_surface *focused_surface,
|
static void get_parent_and_output_box(struct wlr_surface *focused_surface,
|
||||||
struct wlr_box *parent,
|
struct wlr_box *parent, struct wlr_box *output_box) {
|
||||||
struct wlr_box *output_box) {
|
|
||||||
struct wlr_output *output;
|
struct wlr_output *output;
|
||||||
struct wlr_box output_box_tmp;
|
struct wlr_box output_box_tmp;
|
||||||
struct wlr_layer_surface_v1 *layer_surface;
|
struct wlr_layer_surface_v1 *layer_surface;
|
||||||
Client *client = NULL;
|
|
||||||
LayerSurface *l = NULL;
|
|
||||||
|
|
||||||
if ((layer_surface =
|
if ((layer_surface=wlr_layer_surface_v1_try_from_wlr_surface(focused_surface))) {
|
||||||
wlr_layer_surface_v1_try_from_wlr_surface(focused_surface))) {
|
|
||||||
LayerSurface* layer =
|
LayerSurface* layer =
|
||||||
layer_surface_from_wlr_layer_surface_v1(layer_surface);
|
layer_surface_from_wlr_layer_surface_v1(layer_surface);
|
||||||
output = layer->layer_surface->output;
|
output = layer->layer_surface->output;
|
||||||
|
|
@ -421,51 +442,39 @@ static void get_parent_and_output_box(struct wlr_surface *focused_surface,
|
||||||
*parent = layer->geom;
|
*parent = layer->geom;
|
||||||
parent->x += output_box_tmp.x;
|
parent->x += output_box_tmp.x;
|
||||||
parent->y += output_box_tmp.y;
|
parent->y += output_box_tmp.y;
|
||||||
wlr_log(WLR_INFO,
|
wlr_log(WLR_INFO,"get_parent_and_output_box layersurface output_box_tmp->x %d y %d",output_box_tmp.x, output_box_tmp.y);
|
||||||
"get_parent_and_output_box layersurface output_box_tmp->x %d y %d",
|
wlr_log(WLR_INFO,"get_parent_and_output_box layersurface parent->x %d y %d",parent->x,parent->y);
|
||||||
output_box_tmp.x, output_box_tmp.y);
|
|
||||||
wlr_log(WLR_INFO,
|
|
||||||
"get_parent_and_output_box layersurface parent->x %d y %d",
|
|
||||||
parent->x, parent->y);
|
|
||||||
} else {
|
} else {
|
||||||
|
//Client *client = client_from_wlr_surface(focused_surface);
|
||||||
|
Client *client = NULL;
|
||||||
|
LayerSurface *l = NULL;
|
||||||
toplevel_from_wlr_surface(focused_surface, &client, &l);
|
toplevel_from_wlr_surface(focused_surface, &client, &l);
|
||||||
|
|
||||||
output = wlr_output_layout_output_at(output_layout, client->geom.x,
|
output = wlr_output_layout_output_at(output_layout,
|
||||||
client->geom.y);
|
client->geom.x, client->geom.y);
|
||||||
wlr_output_layout_get_box(output_layout, output,&output_box_tmp);
|
wlr_output_layout_get_box(output_layout, output,&output_box_tmp);
|
||||||
|
|
||||||
parent->x = client->geom.x + client->bw;
|
parent->x = client->geom.x + client->bw;
|
||||||
parent->y = client->geom.y + client->bw;
|
parent->y = client->geom.y + client->bw;
|
||||||
parent->width = client->geom.width;
|
parent->width = client->geom.width;
|
||||||
parent->height = client->geom.height;
|
parent->height = client->geom.height;
|
||||||
wlr_log(WLR_INFO,
|
wlr_log(WLR_INFO,"get_parent_and_output_box client output_box_tmp->x %d y %d",output_box_tmp.x, output_box_tmp.y);
|
||||||
"get_parent_and_output_box client output_box_tmp->x %d y %d",
|
wlr_log(WLR_INFO,"get_parent_and_output_box client client->geom.x %d y %d",client->geom.x,client->geom.y);
|
||||||
output_box_tmp.x, output_box_tmp.y);
|
wlr_log(WLR_INFO,"get_parent_and_output_box client client->bw %d",client->bw);
|
||||||
wlr_log(WLR_INFO,
|
wlr_log(WLR_INFO,"get_parent_and_output_box client parent->x %d y %d",parent->x,parent->y);
|
||||||
"get_parent_and_output_box client client->geom.x %d y %d",
|
|
||||||
client->geom.x, client->geom.y);
|
|
||||||
wlr_log(WLR_INFO, "get_parent_and_output_box client client->bw %d",
|
|
||||||
client->bw);
|
|
||||||
wlr_log(WLR_INFO, "get_parent_and_output_box client parent->x %d y %d",
|
|
||||||
parent->x, parent->y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//*output_box = output_box_tmp;
|
//*output_box = output_box_tmp;
|
||||||
memcpy(output_box,&output_box_tmp,sizeof(struct wlr_box));
|
memcpy(output_box,&output_box_tmp,sizeof(struct wlr_box));
|
||||||
wlr_log(WLR_INFO,
|
wlr_log(WLR_INFO,"get_parent_and_output_box output_box x %d y %d width %d height %d",output_box->x,output_box->y,output_box->width,output_box->height);
|
||||||
"get_parent_and_output_box output_box x %d y %d width %d height %d",
|
|
||||||
output_box->x, output_box->y, output_box->width, output_box->height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果当前focused wlr_text_input_v3.features 满足
|
// 如果当前focused wlr_text_input_v3.features 满足 WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE, 不含这个feature就弹出在父窗口左上角
|
||||||
// WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE,
|
// 根据 wlr_text_input_v3.current.cursor_rectangle 计算出一个wlr_box
|
||||||
// 不含这个feature就弹出在父窗口左上角 根据
|
// 再调用 wlr_input_popup_surface_v2_send_text_input_rectangle 和 wlr_scene_node_set_position
|
||||||
// wlr_text_input_v3.current.cursor_rectangle 计算出一个wlr_box 再调用
|
|
||||||
// wlr_input_popup_surface_v2_send_text_input_rectangle 和
|
|
||||||
// wlr_scene_node_set_position
|
|
||||||
static void input_popup_update(struct dwl_input_popup *popup) {
|
static void input_popup_update(struct dwl_input_popup *popup) {
|
||||||
struct wlr_surface* focused_surface;
|
struct wlr_surface* focused_surface;
|
||||||
struct wlr_box output_box, parent, input_cursor;
|
struct wlr_box output_box, parent, cursor;
|
||||||
int x1, x2, y1, y2, x, y, available_right, available_left, available_down,
|
int x1, x2, y1, y2, x, y, available_right, available_left, available_down,
|
||||||
available_up, popup_width, popup_height;
|
available_up, popup_width, popup_height;
|
||||||
bool cursor_rect, x1_in_bounds, y1_in_bounds, x2_in_bounds, y2_in_bounds;
|
bool cursor_rect, x1_in_bounds, y1_in_bounds, x2_in_bounds, y2_in_bounds;
|
||||||
|
|
@ -476,18 +485,17 @@ static void input_popup_update(struct dwl_input_popup *popup) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
//TODO: https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/743da5c0ae723098fe772aadb93810f60e700ab9
|
||||||
// https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/743da5c0ae723098fe772aadb93810f60e700ab9
|
|
||||||
|
|
||||||
if (!popup->popup_surface->surface->mapped) {
|
if (!popup->popup_surface->surface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor_rect = text_input->input->current.features &
|
cursor_rect = text_input->input->current.features
|
||||||
WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE;
|
& WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE;
|
||||||
|
|
||||||
focused_surface = text_input->input->focused_surface;
|
focused_surface = text_input->input->focused_surface;
|
||||||
input_cursor = text_input->input->current.cursor_rectangle;
|
cursor = text_input->input->current.cursor_rectangle;
|
||||||
|
|
||||||
get_parent_and_output_box(focused_surface, &parent, &output_box);
|
get_parent_and_output_box(focused_surface, &parent, &output_box);
|
||||||
|
|
||||||
|
|
@ -495,92 +503,80 @@ static void input_popup_update(struct dwl_input_popup *popup) {
|
||||||
popup_height = popup->popup_surface->surface->current.height;
|
popup_height = popup->popup_surface->surface->current.height;
|
||||||
|
|
||||||
if (!cursor_rect) {
|
if (!cursor_rect) {
|
||||||
input_cursor.x = 0;
|
cursor.x = 0;
|
||||||
input_cursor.y = 0;
|
cursor.y = 0;
|
||||||
input_cursor.width = parent.width;
|
cursor.width = parent.width;
|
||||||
input_cursor.height = parent.height;
|
cursor.height = parent.height;
|
||||||
wlr_log(WLR_INFO,"input_popup_update !cursor_rect");
|
wlr_log(WLR_INFO,"input_popup_update !cursor_rect");
|
||||||
|
|
||||||
popup->x=parent.x;
|
popup->x=parent.x;
|
||||||
popup->y=parent.y;
|
popup->y=parent.y;
|
||||||
popup->visible=true;
|
popup->visible=true;
|
||||||
} else {
|
}
|
||||||
wlr_log(WLR_INFO,
|
else {
|
||||||
"input_popup_update input_cursor x %d y %d width %d height %d",
|
wlr_log(WLR_INFO,"input_popup_update cursor x %d y %d width %d height %d",cursor.x,cursor.y,cursor.width,cursor.height);
|
||||||
input_cursor.x, input_cursor.y, input_cursor.width,
|
|
||||||
input_cursor.height);
|
|
||||||
|
|
||||||
x1 = parent.x + input_cursor.x;
|
x1 = parent.x + cursor.x;
|
||||||
x2 = parent.x + input_cursor.x + input_cursor.width;
|
x2 = parent.x + cursor.x + cursor.width;
|
||||||
y1 = parent.y + input_cursor.y;
|
y1 = parent.y + cursor.y;
|
||||||
y2 = parent.y + input_cursor.y + input_cursor.height;
|
y2 = parent.y + cursor.y + cursor.height;
|
||||||
x = x1;
|
x = x1;
|
||||||
y = y2;
|
y = y2;
|
||||||
|
|
||||||
wlr_log(WLR_INFO, "input_popup_update x1 %d x2 %d y1 %d y2 %d; x %d y %d",
|
wlr_log(WLR_INFO,"input_popup_update x1 %d x2 %d y1 %d y2 %d; x %d y %d",x1,x2,y1,y2,x,y);
|
||||||
x1, x2, y1, y2, x, y);
|
|
||||||
available_right = output_box.x + output_box.width - x1;
|
available_right = output_box.x + output_box.width - x1;
|
||||||
available_left = x2 - output_box.x;
|
available_left = x2 - output_box.x;
|
||||||
if (available_right < popup_width && available_left > available_right) {
|
if (available_right < popup_width && available_left > available_right) {
|
||||||
x = x2 - popup_width;
|
x = x2 - popup_width;
|
||||||
wlr_log(WLR_INFO,
|
wlr_log(WLR_INFO,"input_popup_update available_left %d popup_width %d available_right %d; x %d",available_left,popup_width,available_right,x);
|
||||||
"input_popup_update available_left %d popup_width %d "
|
|
||||||
"available_right %d; x %d",
|
|
||||||
available_left, popup_width, available_right, x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
available_down = output_box.y + output_box.height - y2;
|
available_down = output_box.y + output_box.height - y2;
|
||||||
available_up = y1 - output_box.y;
|
available_up = y1 - output_box.y;
|
||||||
if (available_down < popup_height && available_up > available_down) {
|
if (available_down < popup_height && available_up > available_down) {
|
||||||
y = y1 - popup_height;
|
y = y1 - popup_height;
|
||||||
wlr_log(WLR_INFO,
|
wlr_log(WLR_INFO,"input_popup_update available up %d popup_height %d available_down %d; y %d",available_up,popup_height,available_down,y);
|
||||||
"input_popup_update available up %d popup_height %d "
|
|
||||||
"available_down %d; y %d",
|
|
||||||
available_up, popup_height, available_down, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
popup->x = x;
|
popup->x = x;
|
||||||
popup->y = y;
|
popup->y = y;
|
||||||
|
|
||||||
// Hide popup if input_cursor position is completely out of bounds
|
// Hide popup if cursor position is completely out of bounds
|
||||||
x1_in_bounds = (input_cursor.x >= 0 && input_cursor.x < parent.width);
|
x1_in_bounds = (cursor.x >= 0 && cursor.x < parent.width);
|
||||||
y1_in_bounds = (input_cursor.y >= 0 && input_cursor.y < parent.height);
|
y1_in_bounds = (cursor.y >= 0 && cursor.y < parent.height);
|
||||||
x2_in_bounds = (input_cursor.x + input_cursor.width >= 0 &&
|
x2_in_bounds = (cursor.x + cursor.width >= 0
|
||||||
input_cursor.x + input_cursor.width < parent.width);
|
&& cursor.x + cursor.width < parent.width);
|
||||||
y2_in_bounds = (input_cursor.y + input_cursor.height >= 0 &&
|
y2_in_bounds = (cursor.y + cursor.height >= 0
|
||||||
input_cursor.y + input_cursor.height < parent.height);
|
&& cursor.y + cursor.height < parent.height);
|
||||||
popup->visible =
|
popup->visible =
|
||||||
(x1_in_bounds && y1_in_bounds) || (x2_in_bounds && y2_in_bounds);
|
(x1_in_bounds && y1_in_bounds) || (x2_in_bounds && y2_in_bounds);
|
||||||
|
|
||||||
struct wlr_box box = {
|
struct wlr_box box = {
|
||||||
.x = x1 - x,
|
.x = x1 - x,
|
||||||
.y = y1 - y,
|
.y = y1 - y,
|
||||||
.width = input_cursor.width,
|
.width = cursor.width,
|
||||||
.height = input_cursor.height,
|
.height = cursor.height,
|
||||||
};
|
};
|
||||||
wlr_input_popup_surface_v2_send_text_input_rectangle(popup->popup_surface,
|
wlr_input_popup_surface_v2_send_text_input_rectangle(
|
||||||
&box);
|
popup->popup_surface, &box);
|
||||||
wlr_log(WLR_INFO,
|
wlr_log(WLR_INFO,"input_popup_update send_text_input_rect box.x %d box.y %d",box.x,box.y);
|
||||||
"input_popup_update send_text_input_rect box.x %d box.y %d", box.x,
|
|
||||||
box.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_log(WLR_INFO, "input_popup_update x %d y %d visible %s", popup->x,
|
wlr_log(WLR_INFO,"input_popup_update x %d y %d visible %s",popup->x,popup->y,popup->visible?"true":"false");
|
||||||
popup->y, popup->visible ? "true" : "false");
|
|
||||||
wlr_scene_node_set_position(&popup->scene->node, popup->x, popup->y);
|
wlr_scene_node_set_position(&popup->scene->node, popup->x, popup->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_im_popup_map(struct wl_listener *listener, void *data) {
|
static void handle_im_popup_map(struct wl_listener *listener, void *data) {
|
||||||
struct dwl_input_popup *popup = wl_container_of(listener, popup, popup_map);
|
struct dwl_input_popup *popup =
|
||||||
|
wl_container_of(listener, popup, popup_map);
|
||||||
|
|
||||||
wlr_log(WLR_INFO, "IM_popup_map");
|
wlr_log(WLR_INFO, "IM_popup_map");
|
||||||
|
|
||||||
//popup->scene = &wlr_scene_tree_create(layers[LyrIMPopup])->node;
|
//popup->scene = &wlr_scene_tree_create(layers[LyrIMPopup])->node;
|
||||||
popup->scene = wlr_scene_tree_create(layers[LyrIMPopup]);
|
popup->scene = wlr_scene_tree_create(layers[LyrIMPopup]);
|
||||||
popup->scene_surface = wlr_scene_subsurface_tree_create(
|
popup->scene_surface = wlr_scene_subsurface_tree_create(popup->scene,popup->popup_surface->surface);
|
||||||
popup->scene, popup->popup_surface->surface);
|
//popup->scene_surface = &wlr_scene_subsurface_tree_create(popup->scene->parent,popup->popup_surface->surface)->node;
|
||||||
// popup->scene_surface =
|
|
||||||
// &wlr_scene_subsurface_tree_create(popup->scene->parent,popup->popup_surface->surface)->node;
|
|
||||||
//popup->scene_surface->data = popup;
|
//popup->scene_surface->data = popup;
|
||||||
popup->scene_surface->node.data = popup;
|
popup->scene_surface->node.data = popup;
|
||||||
|
|
||||||
|
|
@ -590,7 +586,8 @@ static void handle_im_popup_map(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_im_popup_unmap(struct wl_listener *listener, void *data) {
|
static void handle_im_popup_unmap(struct wl_listener *listener, void *data) {
|
||||||
struct dwl_input_popup *popup = wl_container_of(listener, popup, popup_unmap);
|
struct dwl_input_popup *popup =
|
||||||
|
wl_container_of(listener, popup, popup_unmap);
|
||||||
//input_popup_update(popup);
|
//input_popup_update(popup);
|
||||||
|
|
||||||
wlr_log(WLR_INFO,"im_popup_unmap");
|
wlr_log(WLR_INFO,"im_popup_unmap");
|
||||||
|
|
@ -613,12 +610,12 @@ static void handle_im_popup_destroy(struct wl_listener *listener, void *data) {
|
||||||
relay->popup=NULL;
|
relay->popup=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_im_new_popup_surface(struct wl_listener *listener,
|
|
||||||
void *data) {
|
static void handle_im_new_popup_surface(struct wl_listener *listener, void *data) {
|
||||||
// struct dwl_text_input* text_input;
|
// struct dwl_text_input* text_input;
|
||||||
|
|
||||||
struct dwl_input_method_relay *relay =
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
wl_container_of(listener, relay, input_method_new_popup_surface);
|
input_method_new_popup_surface);
|
||||||
struct dwl_input_popup *popup = calloc(1, sizeof(*popup));
|
struct dwl_input_popup *popup = calloc(1, sizeof(*popup));
|
||||||
|
|
||||||
wlr_log(WLR_INFO, "IM_new_popup_surface");
|
wlr_log(WLR_INFO, "IM_new_popup_surface");
|
||||||
|
|
@ -628,23 +625,25 @@ static void handle_im_new_popup_surface(struct wl_listener *listener,
|
||||||
popup->popup_surface = data;
|
popup->popup_surface = data;
|
||||||
popup->popup_surface->data = popup;
|
popup->popup_surface->data = popup;
|
||||||
|
|
||||||
|
|
||||||
wl_signal_add(&popup->popup_surface->surface->events.map, &popup->popup_map);
|
wl_signal_add(&popup->popup_surface->surface->events.map, &popup->popup_map);
|
||||||
popup->popup_map.notify = handle_im_popup_map;
|
popup->popup_map.notify = handle_im_popup_map;
|
||||||
|
|
||||||
wl_signal_add(&popup->popup_surface->surface->events.unmap,
|
wl_signal_add(&popup->popup_surface->surface->events.unmap, &popup->popup_unmap);
|
||||||
&popup->popup_unmap);
|
|
||||||
popup->popup_unmap.notify = handle_im_popup_unmap;
|
popup->popup_unmap.notify = handle_im_popup_unmap;
|
||||||
|
|
||||||
wl_signal_add(&popup->popup_surface->events.destroy, &popup->popup_destroy);
|
wl_signal_add(
|
||||||
|
&popup->popup_surface->events.destroy, &popup->popup_destroy);
|
||||||
popup->popup_destroy.notify = handle_im_popup_destroy;
|
popup->popup_destroy.notify = handle_im_popup_destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void relay_handle_input_method_new(struct wl_listener *listener,
|
static void relay_handle_input_method_new(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct dwl_text_input *text_input;
|
struct dwl_text_input *text_input;
|
||||||
|
|
||||||
struct dwl_input_method_relay *relay =
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
wl_container_of(listener, relay, input_method_new);
|
input_method_new);
|
||||||
|
|
||||||
struct wlr_input_method_v2 *input_method = data;
|
struct wlr_input_method_v2 *input_method = data;
|
||||||
if (seat != input_method->seat) {
|
if (seat != input_method->seat) {
|
||||||
|
|
@ -653,9 +652,7 @@ static void relay_handle_input_method_new(struct wl_listener *listener,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (relay->input_method != NULL) {
|
if (relay->input_method != NULL) {
|
||||||
wlr_log(
|
wlr_log(WLR_INFO, "input_method_new Attempted to connect second input method to a seat");
|
||||||
WLR_INFO,
|
|
||||||
"input_method_new Attempted to connect second input method to a seat");
|
|
||||||
wlr_input_method_v2_send_unavailable(input_method);
|
wlr_input_method_v2_send_unavailable(input_method);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -692,7 +689,8 @@ void dwl_input_method_relay_init(struct dwl_input_method_relay *relay) {
|
||||||
relay->popup=NULL;
|
relay->popup=NULL;
|
||||||
|
|
||||||
relay->text_input_new.notify = relay_handle_text_input_new;
|
relay->text_input_new.notify = relay_handle_text_input_new;
|
||||||
wl_signal_add(&text_input_manager->events.text_input, &relay->text_input_new);
|
wl_signal_add(&text_input_manager->events.text_input,
|
||||||
|
&relay->text_input_new);
|
||||||
|
|
||||||
relay->input_method_new.notify = relay_handle_input_method_new;
|
relay->input_method_new.notify = relay_handle_input_method_new;
|
||||||
wl_signal_add(&input_method_manager->events.input_method,
|
wl_signal_add(&input_method_manager->events.input_method,
|
||||||
|
|
@ -720,13 +718,13 @@ void dwl_input_method_relay_set_focus(struct dwl_input_method_relay *relay,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (surface && wl_resource_get_client(text_input->input->resource) ==
|
if (surface
|
||||||
wl_resource_get_client(surface->resource)) {
|
&& wl_resource_get_client(text_input->input->resource)
|
||||||
|
== wl_resource_get_client(surface->resource)) {
|
||||||
if (relay->input_method) {
|
if (relay->input_method) {
|
||||||
wlr_text_input_v3_send_enter(text_input->input, surface);
|
wlr_text_input_v3_send_enter(text_input->input, surface);
|
||||||
wlr_log(WLR_INFO, "wlr_text_input_send_enter");
|
wlr_log(WLR_INFO, "wlr_text_input_send_enter");
|
||||||
if (relay->popup)
|
if (relay->popup) input_popup_update(relay->popup);
|
||||||
input_popup_update(relay->popup);
|
|
||||||
} else {
|
} else {
|
||||||
text_input_set_pending_focused_surface(text_input, surface);
|
text_input_set_pending_focused_surface(text_input, surface);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
28
README.md
28
README.md
|
|
@ -41,7 +41,8 @@ See below for more features.
|
||||||
- isfloating: type-num(0 or 1)
|
- isfloating: type-num(0 or 1)
|
||||||
- isfullscreen: type-num(0 or 1)
|
- isfullscreen: type-num(0 or 1)
|
||||||
- scroller_proportion: type-float(0.1-1.0)
|
- scroller_proportion: type-float(0.1-1.0)
|
||||||
- animation_type : type-string(zoom,slide)
|
- animation_type_open : type-string(zoom,slide)
|
||||||
|
- animation_type_close : type-string(zoom,slide)
|
||||||
- isnoborder : type-num(0 or 1)
|
- isnoborder : type-num(0 or 1)
|
||||||
- monitor : type-num(0-99999)
|
- monitor : type-num(0-99999)
|
||||||
- width : type-num(0-9999)
|
- width : type-num(0-9999)
|
||||||
|
|
@ -62,17 +63,15 @@ See below for more features.
|
||||||
- alt-tab switch window like gnome
|
- alt-tab switch window like gnome
|
||||||
- niri like scroller layout
|
- niri like scroller layout
|
||||||
|
|
||||||
## suggest tools
|
|
||||||
```
|
|
||||||
yay -S rofi foot xdg-desktop-portal-wlr swaybg waybar wl-clip-persist cliphist wl-clipboard wlsunset
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
# install
|
# install
|
||||||
## stable - wlroots(0.17)
|
## stable - wlroots(0.17)
|
||||||
Since 0.18 has some bugs that affect the experience,
|
Since 0.18 has some bugs that affect the experience,
|
||||||
I chose the more stable 0.17.4.
|
I chose the more stable 0.17.4.
|
||||||
|
- Arch
|
||||||
|
```
|
||||||
|
yay -S maomaowm-git
|
||||||
|
```
|
||||||
|
- Other
|
||||||
```
|
```
|
||||||
yay -S libinput
|
yay -S libinput
|
||||||
git clone -b 0.17.4 https://gitlab.freedesktop.org/wlroots/wlroots.git
|
git clone -b 0.17.4 https://gitlab.freedesktop.org/wlroots/wlroots.git
|
||||||
|
|
@ -99,7 +98,18 @@ meson build -Dprefix=/usr
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## suggest tools
|
||||||
|
```
|
||||||
|
yay -S rofi foot xdg-desktop-portal-wlr swaybg waybar wl-clip-persist cliphist wl-clipboard wlsunset
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
# config
|
# config
|
||||||
|
```
|
||||||
|
cp /etc/maomao/config.conf ~/.config/maomao/config.conf
|
||||||
|
touch ~/.config/maomao/autostart.sh
|
||||||
|
chmod +x ~/.config/maomao/autostart.sh
|
||||||
|
```
|
||||||
you can use `MAOMAOCONFIG` env to set the config-folder-path and the autostart-folder-patch
|
you can use `MAOMAOCONFIG` env to set the config-folder-path and the autostart-folder-patch
|
||||||
like `MAOMAOCONFIG=/home/xxx/maomao`
|
like `MAOMAOCONFIG=/home/xxx/maomao`
|
||||||
|
|
||||||
|
|
@ -162,7 +172,7 @@ ov_tab_mode=0
|
||||||
### notice
|
### notice
|
||||||
when you in ov mode, you can use right mouse button to close window, and left mouse button to jump to a window.
|
when you in ov mode, you can use right mouse button to close window, and left mouse button to jump to a window.
|
||||||
|
|
||||||
# About warbar
|
# About waybar
|
||||||
|
|
||||||
- you can also use the dwl moudle in waybar to show tags and window title
|
- you can also use the dwl moudle in waybar to show tags and window title
|
||||||
refer to waybar wiki: [dwl-module](https://github.com/Alexays/Waybar/wiki/Module:-Dwl)
|
refer to waybar wiki: [dwl-module](https://github.com/Alexays/Waybar/wiki/Module:-Dwl)
|
||||||
|
|
|
||||||
12
config.conf
12
config.conf
|
|
@ -1,12 +1,13 @@
|
||||||
# Animation Configuration
|
# Animation Configuration
|
||||||
animations=1
|
animations=1
|
||||||
animation_type=slide
|
animation_type_open=zoom
|
||||||
|
animation_type_close=slide
|
||||||
animation_fade_in=1
|
animation_fade_in=1
|
||||||
zoom_initial_ratio=0.5
|
zoom_initial_ratio=0.5
|
||||||
fadein_begin_opacity=0.5
|
fadein_begin_opacity=0.5
|
||||||
fadeout_begin_opacity=0.8
|
fadeout_begin_opacity=0.8
|
||||||
animation_duration_move=400
|
animation_duration_move=500
|
||||||
animation_duration_open=350
|
animation_duration_open=400
|
||||||
animation_duration_tag=350
|
animation_duration_tag=350
|
||||||
animation_duration_close=800
|
animation_duration_close=800
|
||||||
animation_curve_open=0.46,1.0,0.29,1
|
animation_curve_open=0.46,1.0,0.29,1
|
||||||
|
|
@ -94,7 +95,8 @@ tags=id:9,layout_name:tile
|
||||||
# isfloating: type-num(0 or 1)
|
# isfloating: type-num(0 or 1)
|
||||||
# isfullscreen: type-num(0 or 1)
|
# isfullscreen: type-num(0 or 1)
|
||||||
# scroller_proportion: type-float(0.1-1.0)
|
# scroller_proportion: type-float(0.1-1.0)
|
||||||
# animation_type : type-string(zoom,slide)
|
# animation_type_open : type-string(zoom,slide)
|
||||||
|
# animation_type_close : type-string(zoom,slide)
|
||||||
# isnoborder : type-num(0 or 1)
|
# isnoborder : type-num(0 or 1)
|
||||||
# monitor : type-int(0-99999)
|
# monitor : type-int(0-99999)
|
||||||
# width : type-num(0-9999)
|
# width : type-num(0-9999)
|
||||||
|
|
@ -110,7 +112,7 @@ tags=id:9,layout_name:tile
|
||||||
# windowrule=isfloating:1,appid:Rofi
|
# windowrule=isfloating:1,appid:Rofi
|
||||||
# windowrule=isfloating:1,appid:wofi
|
# windowrule=isfloating:1,appid:wofi
|
||||||
# windowrule=isnoborder:1,appid:wofi
|
# windowrule=isnoborder:1,appid:wofi
|
||||||
# windowrule=animation_type:zoom,appid:wofi
|
# windowrule=animation_type_open:zoom,appid:wofi
|
||||||
|
|
||||||
# open in specific tag
|
# open in specific tag
|
||||||
# windowrule=tags:4,appid:Google-chrome
|
# windowrule=tags:4,appid:Google-chrome
|
||||||
|
|
|
||||||
311
maomao.c
311
maomao.c
|
|
@ -15,9 +15,11 @@
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
#include <wlr/backend/libinput.h>
|
#include <wlr/backend/libinput.h>
|
||||||
|
#include <wlr/interfaces/wlr_keyboard.h>
|
||||||
#include <wlr/render/allocator.h>
|
#include <wlr/render/allocator.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
#include <wlr/types/wlr_alpha_modifier_v1.h>
|
#include <wlr/types/wlr_alpha_modifier_v1.h>
|
||||||
|
#include <wlr/types/wlr_keyboard_group.h>
|
||||||
#include <wlr/types/wlr_compositor.h>
|
#include <wlr/types/wlr_compositor.h>
|
||||||
#include <wlr/types/wlr_cursor.h>
|
#include <wlr/types/wlr_cursor.h>
|
||||||
#include <wlr/types/wlr_data_control_v1.h>
|
#include <wlr/types/wlr_data_control_v1.h>
|
||||||
|
|
@ -232,7 +234,8 @@ struct Client {
|
||||||
struct wl_listener destroy_decoration;
|
struct wl_listener destroy_decoration;
|
||||||
|
|
||||||
unsigned int ignore_clear_fullscreen;
|
unsigned int ignore_clear_fullscreen;
|
||||||
const char *animation_type;
|
const char *animation_type_open;
|
||||||
|
const char *animation_type_close;
|
||||||
int is_in_scratchpad;
|
int is_in_scratchpad;
|
||||||
int is_scratchpad_show;
|
int is_scratchpad_show;
|
||||||
int isglobal;
|
int isglobal;
|
||||||
|
|
@ -266,6 +269,19 @@ typedef struct {
|
||||||
const Arg arg;
|
const Arg arg;
|
||||||
} Key;
|
} Key;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct wlr_keyboard_group *wlr_group;
|
||||||
|
|
||||||
|
int nsyms;
|
||||||
|
const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */
|
||||||
|
uint32_t mods; /* invalid if nsyms == 0 */
|
||||||
|
struct wl_event_source *key_repeat_source;
|
||||||
|
|
||||||
|
struct wl_listener modifiers;
|
||||||
|
struct wl_listener key;
|
||||||
|
struct wl_listener destroy;
|
||||||
|
} KeyboardGroup;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct wlr_keyboard *wlr_keyboard;
|
struct wlr_keyboard *wlr_keyboard;
|
||||||
|
|
@ -357,7 +373,8 @@ typedef struct {
|
||||||
int isfloating;
|
int isfloating;
|
||||||
int isfullscreen;
|
int isfullscreen;
|
||||||
float scroller_proportion;
|
float scroller_proportion;
|
||||||
const char *animation_type;
|
const char *animation_type_open;
|
||||||
|
const char *animation_type_close;
|
||||||
int isnoborder;
|
int isnoborder;
|
||||||
int monitor;
|
int monitor;
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
|
|
@ -425,6 +442,7 @@ static void destroylocksurface(struct wl_listener *listener, void *data);
|
||||||
static void destroynotify(struct wl_listener *listener, void *data);
|
static void destroynotify(struct wl_listener *listener, void *data);
|
||||||
static void destroypointerconstraint(struct wl_listener *listener, void *data);
|
static void destroypointerconstraint(struct wl_listener *listener, void *data);
|
||||||
static void destroysessionlock(struct wl_listener *listener, void *data);
|
static void destroysessionlock(struct wl_listener *listener, void *data);
|
||||||
|
static void destroykeyboardgroup(struct wl_listener *listener, void *data);
|
||||||
static Monitor *dirtomon(enum wlr_direction dir);
|
static Monitor *dirtomon(enum wlr_direction dir);
|
||||||
static void setcursorshape(struct wl_listener *listener, void *data);
|
static void setcursorshape(struct wl_listener *listener, void *data);
|
||||||
static void dwl_ipc_manager_bind(struct wl_client *client, void *data,
|
static void dwl_ipc_manager_bind(struct wl_client *client, void *data,
|
||||||
|
|
@ -589,6 +607,7 @@ static const char broken[] = "broken";
|
||||||
// static const char *cursor_image = "left_ptr";
|
// static const char *cursor_image = "left_ptr";
|
||||||
static pid_t child_pid = -1;
|
static pid_t child_pid = -1;
|
||||||
static int locked;
|
static int locked;
|
||||||
|
static uint32_t locked_mods = 0;
|
||||||
static void *exclusive_focus;
|
static void *exclusive_focus;
|
||||||
static struct wl_display *dpy;
|
static struct wl_display *dpy;
|
||||||
static struct wl_event_loop *event_loop;
|
static struct wl_event_loop *event_loop;
|
||||||
|
|
@ -633,6 +652,7 @@ static struct wlr_relative_pointer_manager_v1 *relative_pointer_mgr;
|
||||||
static struct wlr_pointer_constraint_v1 *active_constraint;
|
static struct wlr_pointer_constraint_v1 *active_constraint;
|
||||||
|
|
||||||
static struct wlr_seat *seat;
|
static struct wlr_seat *seat;
|
||||||
|
static KeyboardGroup *kb_group;
|
||||||
static struct wl_list keyboards;
|
static struct wl_list keyboards;
|
||||||
static unsigned int cursor_mode;
|
static unsigned int cursor_mode;
|
||||||
static Client *grabc;
|
static Client *grabc;
|
||||||
|
|
@ -897,8 +917,8 @@ void fadeout_client_animation_next_tick(Client *c) {
|
||||||
|
|
||||||
apply_opacity_to_rect_nodes(c, &c->scene->node, animation_passed);
|
apply_opacity_to_rect_nodes(c, &c->scene->node, animation_passed);
|
||||||
|
|
||||||
if ((c->animation_type && strcmp(c->animation_type, "zoom") == 0) ||
|
if ((c->animation_type_close && strcmp(c->animation_type_close, "zoom") == 0) ||
|
||||||
(!c->animation_type && strcmp(animation_type, "zoom") == 0)) {
|
(!c->animation_type_close && strcmp(animation_type_close, "zoom") == 0)) {
|
||||||
|
|
||||||
scale_data.width = width;
|
scale_data.width = width;
|
||||||
scale_data.height = height;
|
scale_data.height = height;
|
||||||
|
|
@ -1015,12 +1035,12 @@ void apply_border(Client *c, struct wlr_box clip_box, int offsetx,
|
||||||
if (c->animation.running && c->animation.action != MOVE) {
|
if (c->animation.running && c->animation.action != MOVE) {
|
||||||
if (c->animation.current.x < c->mon->m.x) {
|
if (c->animation.current.x < c->mon->m.x) {
|
||||||
wlr_scene_rect_set_size(c->border[2], 0, 0);
|
wlr_scene_rect_set_size(c->border[2], 0, 0);
|
||||||
} else if (c->animation.current.x + c->geom.width >
|
} else if (c->animation.current.x + c->animation.current.width >
|
||||||
c->mon->m.x + c->mon->m.width) {
|
c->mon->m.x + c->mon->m.width) {
|
||||||
wlr_scene_rect_set_size(c->border[3], 0, 0);
|
wlr_scene_rect_set_size(c->border[3], 0, 0);
|
||||||
} else if (c->animation.current.y < c->mon->m.y) {
|
} else if (c->animation.current.y < c->mon->m.y) {
|
||||||
wlr_scene_rect_set_size(c->border[0], 0, 0);
|
wlr_scene_rect_set_size(c->border[0], 0, 0);
|
||||||
} else if (c->animation.current.y + c->geom.height >
|
} else if (c->animation.current.y + c->animation.current.height >
|
||||||
c->mon->m.y + c->mon->m.height) {
|
c->mon->m.y + c->mon->m.height) {
|
||||||
wlr_scene_rect_set_size(c->border[1], 0, 0);
|
wlr_scene_rect_set_size(c->border[1], 0, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -1070,13 +1090,13 @@ void client_apply_clip(Client *c) {
|
||||||
clip_box.y = 0;
|
clip_box.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make tagout tagin animations not visible in other monitors
|
// // make tagout tagin animations not visible in other monitors
|
||||||
if (c->animation.running && c->animation.action != MOVE) {
|
if (c->animation.running && c->animation.action != MOVE) {
|
||||||
if (c->animation.current.x <= c->mon->m.x) {
|
if (c->animation.current.x <= c->mon->m.x) {
|
||||||
offsetx = c->mon->m.x - c->animation.current.x;
|
offsetx = c->mon->m.x - c->animation.current.x;
|
||||||
clip_box.x = clip_box.x + offsetx;
|
clip_box.x = clip_box.x + offsetx;
|
||||||
clip_box.width = clip_box.width - offsetx;
|
clip_box.width = clip_box.width - offsetx;
|
||||||
} else if (c->animation.current.x + c->geom.width >=
|
} else if (c->animation.current.x + c->animation.current.width >=
|
||||||
c->mon->m.x + c->mon->m.width) {
|
c->mon->m.x + c->mon->m.width) {
|
||||||
clip_box.width = clip_box.width -
|
clip_box.width = clip_box.width -
|
||||||
(c->animation.current.x + c->animation.current.width -
|
(c->animation.current.x + c->animation.current.width -
|
||||||
|
|
@ -1087,7 +1107,7 @@ void client_apply_clip(Client *c) {
|
||||||
offsety = c->mon->m.y - c->animation.current.y;
|
offsety = c->mon->m.y - c->animation.current.y;
|
||||||
clip_box.y = clip_box.y + offsety;
|
clip_box.y = clip_box.y + offsety;
|
||||||
clip_box.height = clip_box.height - offsety;
|
clip_box.height = clip_box.height - offsety;
|
||||||
} else if (c->animation.current.y + c->geom.height >=
|
} else if (c->animation.current.y + c->animation.current.height >=
|
||||||
c->mon->m.y + c->mon->m.height) {
|
c->mon->m.y + c->mon->m.height) {
|
||||||
clip_box.height = clip_box.height -
|
clip_box.height = clip_box.height -
|
||||||
(c->animation.current.y + c->animation.current.height -
|
(c->animation.current.y + c->animation.current.height -
|
||||||
|
|
@ -1504,8 +1524,10 @@ applyrules(Client *c) {
|
||||||
c->isterm = r->isterm > 0 ? r->isterm : c->isterm;
|
c->isterm = r->isterm > 0 ? r->isterm : c->isterm;
|
||||||
c->noswallow = r->noswallow > 0? r->noswallow : c->noswallow;
|
c->noswallow = r->noswallow > 0? r->noswallow : c->noswallow;
|
||||||
c->isfloating = r->isfloating > 0 ? r->isfloating : c->isfloating;
|
c->isfloating = r->isfloating > 0 ? r->isfloating : c->isfloating;
|
||||||
c->animation_type =
|
c->animation_type_open =
|
||||||
r->animation_type == NULL ? c->animation_type : r->animation_type;
|
r->animation_type_open == NULL ? c->animation_type_open : r->animation_type_open;
|
||||||
|
c->animation_type_close =
|
||||||
|
r->animation_type_close == NULL ? c->animation_type_close : r->animation_type_close;
|
||||||
c->scroller_proportion = r->scroller_proportion > 0
|
c->scroller_proportion = r->scroller_proportion > 0
|
||||||
? r->scroller_proportion
|
? r->scroller_proportion
|
||||||
: scroller_default_proportion;
|
: scroller_default_proportion;
|
||||||
|
|
@ -2133,6 +2155,7 @@ cleanup(void) {
|
||||||
waitpid(child_pid, NULL, 0);
|
waitpid(child_pid, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroykeyboardgroup(&kb_group->destroy, NULL);
|
||||||
wlr_backend_destroy(backend);
|
wlr_backend_destroy(backend);
|
||||||
wlr_scene_node_destroy(&scene->tree.node);
|
wlr_scene_node_destroy(&scene->tree.node);
|
||||||
wlr_renderer_destroy(drw);
|
wlr_renderer_destroy(drw);
|
||||||
|
|
@ -2381,50 +2404,72 @@ void createidleinhibitor(struct wl_listener *listener, void *data) {
|
||||||
checkidleinhibitor(NULL);
|
checkidleinhibitor(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void // 17
|
void
|
||||||
createkeyboard(struct wlr_keyboard *keyboard) {
|
createkeyboard(struct wlr_keyboard *keyboard)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/* Set the keymap to match the group keymap */
|
||||||
|
wlr_keyboard_set_keymap(keyboard, kb_group->wlr_group->keyboard.keymap);
|
||||||
|
|
||||||
|
wlr_keyboard_notify_modifiers(keyboard, 0, 0, locked_mods, 0);
|
||||||
|
|
||||||
|
/* Add the new keyboard to the group */
|
||||||
|
wlr_keyboard_group_add_keyboard(kb_group->wlr_group, keyboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
KeyboardGroup *
|
||||||
|
createkeyboardgroup(void)
|
||||||
|
{
|
||||||
|
KeyboardGroup *group = ecalloc(1, sizeof(*group));
|
||||||
struct xkb_context *context;
|
struct xkb_context *context;
|
||||||
struct xkb_keymap *keymap;
|
struct xkb_keymap *keymap;
|
||||||
Keyboard *kb = keyboard->data = ecalloc(1, sizeof(*kb));
|
|
||||||
kb->wlr_keyboard = keyboard;
|
|
||||||
|
|
||||||
/* Prepare an XKB keymap and assign it to the keyboard. */
|
group->wlr_group = wlr_keyboard_group_create();
|
||||||
|
group->wlr_group->data = group;
|
||||||
|
|
||||||
|
/* Prepare an XKB keymap and assign it to the keyboard group. */
|
||||||
context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
keymap = xkb_keymap_new_from_names(context, &xkb_rules,
|
if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules,
|
||||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
XKB_KEYMAP_COMPILE_NO_FLAGS)))
|
||||||
|
die("failed to compile keymap");
|
||||||
|
|
||||||
|
wlr_keyboard_set_keymap(&group->wlr_group->keyboard, keymap);
|
||||||
|
|
||||||
|
if (numlockon) {
|
||||||
|
xkb_mod_index_t mod_index = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_NUM);
|
||||||
|
if (mod_index != XKB_MOD_INVALID)
|
||||||
|
locked_mods |= (uint32_t)1 << mod_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (capslock) {
|
||||||
|
xkb_mod_index_t mod_index = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
|
||||||
|
if (mod_index != XKB_MOD_INVALID)
|
||||||
|
locked_mods |= (uint32_t)1 << mod_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (locked_mods)
|
||||||
|
wlr_keyboard_notify_modifiers(&group->wlr_group->keyboard, 0, 0, locked_mods, 0);
|
||||||
|
|
||||||
wlr_keyboard_set_keymap(keyboard, keymap);
|
|
||||||
xkb_keymap_unref(keymap);
|
xkb_keymap_unref(keymap);
|
||||||
xkb_context_unref(context);
|
xkb_context_unref(context);
|
||||||
wlr_keyboard_set_repeat_info(keyboard, repeat_rate, repeat_delay);
|
|
||||||
|
|
||||||
if (numlockon == 1) {
|
wlr_keyboard_set_repeat_info(&group->wlr_group->keyboard, repeat_rate, repeat_delay);
|
||||||
uint32_t leds = 0;
|
|
||||||
xkb_mod_mask_t locked_mods = 0;
|
|
||||||
leds = leds | WLR_LED_NUM_LOCK;
|
|
||||||
// 获取numlock所在的位置
|
|
||||||
xkb_mod_index_t mod_index = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_NUM);
|
|
||||||
if (mod_index != XKB_MOD_INVALID) {
|
|
||||||
locked_mods |= (uint32_t)1
|
|
||||||
<< mod_index; // 将该位置设置为1,默认为0表示锁住小键盘
|
|
||||||
}
|
|
||||||
// 设置numlock为on
|
|
||||||
xkb_state_update_mask(keyboard->xkb_state, 0, 0, locked_mods, 0, 0, 0);
|
|
||||||
wlr_keyboard_led_update(keyboard, leds); // 将表示numlockon的灯打开
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Here we set up listeners for keyboard events. */
|
/* Set up listeners for keyboard events */
|
||||||
LISTEN(&keyboard->events.modifiers, &kb->modifiers, keypressmod);
|
LISTEN(&group->wlr_group->keyboard.events.key, &group->key, keypress);
|
||||||
LISTEN(&keyboard->events.key, &kb->key, keypress);
|
LISTEN(&group->wlr_group->keyboard.events.modifiers, &group->modifiers, keypressmod);
|
||||||
LISTEN(&keyboard->base.events.destroy, &kb->destroy, cleanupkeyboard);
|
|
||||||
|
|
||||||
wlr_seat_set_keyboard(seat, keyboard);
|
group->key_repeat_source = wl_event_loop_add_timer(event_loop, keyrepeat, group);
|
||||||
|
|
||||||
kb->key_repeat_source =
|
/* A seat can only have one keyboard, but this is a limitation of the
|
||||||
wl_event_loop_add_timer(wl_display_get_event_loop(dpy), keyrepeat, kb);
|
* Wayland protocol - not wlroots. We assign all connected keyboards to the
|
||||||
|
* same wlr_keyboard_group, which provides a single wlr_keyboard interface for
|
||||||
/* And add the keyboard to our list of keyboards */
|
* all of them. Set this combined wlr_keyboard as the seat keyboard.
|
||||||
wl_list_insert(&keyboards, &kb->link);
|
*/
|
||||||
|
wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard);
|
||||||
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
void createlayersurface(struct wl_listener *listener, void *data) {
|
void createlayersurface(struct wl_listener *listener, void *data) {
|
||||||
|
|
@ -2839,6 +2884,18 @@ void destroysessionlock(struct wl_listener *listener, void *data) {
|
||||||
destroylock(lock, 0);
|
destroylock(lock, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
destroykeyboardgroup(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
KeyboardGroup *group = wl_container_of(listener, group, destroy);
|
||||||
|
wl_event_source_remove(group->key_repeat_source);
|
||||||
|
wl_list_remove(&group->key.link);
|
||||||
|
wl_list_remove(&group->modifiers.link);
|
||||||
|
wl_list_remove(&group->destroy.link);
|
||||||
|
wlr_keyboard_group_destroy(group->wlr_group);
|
||||||
|
free(group);
|
||||||
|
}
|
||||||
|
|
||||||
Monitor *dirtomon(enum wlr_direction dir) {
|
Monitor *dirtomon(enum wlr_direction dir) {
|
||||||
struct wlr_output *next;
|
struct wlr_output *next;
|
||||||
if (!wlr_output_layout_get(output_layout, selmon->wlr_output))
|
if (!wlr_output_layout_get(output_layout, selmon->wlr_output))
|
||||||
|
|
@ -3278,9 +3335,9 @@ void incovgaps(const Arg *arg) {
|
||||||
setgaps(selmon->gappoh, selmon->gappov + arg->i, selmon->gappih,
|
setgaps(selmon->gappoh, selmon->gappov + arg->i, selmon->gappih,
|
||||||
selmon->gappiv);
|
selmon->gappiv);
|
||||||
}
|
}
|
||||||
|
void
|
||||||
void // 17
|
inputdevice(struct wl_listener *listener, void *data)
|
||||||
inputdevice(struct wl_listener *listener, void *data) {
|
{
|
||||||
/* This event is raised by the backend when a new input device becomes
|
/* This event is raised by the backend when a new input device becomes
|
||||||
* available. */
|
* available. */
|
||||||
struct wlr_input_device *device = data;
|
struct wlr_input_device *device = data;
|
||||||
|
|
@ -3303,22 +3360,24 @@ inputdevice(struct wl_listener *listener, void *data) {
|
||||||
* there are no pointer devices, so we always include that capability. */
|
* there are no pointer devices, so we always include that capability. */
|
||||||
/* TODO do we actually require a cursor? */
|
/* TODO do we actually require a cursor? */
|
||||||
caps = WL_SEAT_CAPABILITY_POINTER;
|
caps = WL_SEAT_CAPABILITY_POINTER;
|
||||||
if (!wl_list_empty(&keyboards))
|
if (!wl_list_empty(&kb_group->wlr_group->devices))
|
||||||
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
|
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
|
||||||
wlr_seat_set_capabilities(seat, caps);
|
wlr_seat_set_capabilities(seat, caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
int keyrepeat(void *data) {
|
int
|
||||||
Keyboard *kb = data;
|
keyrepeat(void *data)
|
||||||
|
{
|
||||||
|
KeyboardGroup *group = data;
|
||||||
int i;
|
int i;
|
||||||
if (!kb->nsyms || kb->wlr_keyboard->repeat_info.rate <= 0)
|
if (!group->nsyms || group->wlr_group->keyboard.repeat_info.rate <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
wl_event_source_timer_update(kb->key_repeat_source,
|
wl_event_source_timer_update(group->key_repeat_source,
|
||||||
1000 / kb->wlr_keyboard->repeat_info.rate);
|
1000 / group->wlr_group->keyboard.repeat_info.rate);
|
||||||
|
|
||||||
for (i = 0; i < kb->nsyms; i++)
|
for (i = 0; i < group->nsyms; i++)
|
||||||
keybinding(kb->mods, kb->keysyms[i]);
|
keybinding(group->mods, group->keysyms[i]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -3345,22 +3404,23 @@ keybinding(uint32_t mods, xkb_keysym_t sym) {
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void // 17
|
void
|
||||||
keypress(struct wl_listener *listener, void *data) {
|
keypress(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
/* This event is raised when a key is pressed or released. */
|
/* This event is raised when a key is pressed or released. */
|
||||||
Keyboard *kb = wl_container_of(listener, kb, key);
|
KeyboardGroup *group = wl_container_of(listener, group, key);
|
||||||
struct wlr_keyboard_key_event *event = data;
|
struct wlr_keyboard_key_event *event = data;
|
||||||
|
|
||||||
/* Translate libinput keycode -> xkbcommon */
|
/* Translate libinput keycode -> xkbcommon */
|
||||||
uint32_t keycode = event->keycode + 8;
|
uint32_t keycode = event->keycode + 8;
|
||||||
/* Get a list of keysyms based on the keymap for this keyboard */
|
/* Get a list of keysyms based on the keymap for this keyboard */
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
int nsyms =
|
int nsyms = xkb_state_key_get_syms(
|
||||||
xkb_state_key_get_syms(kb->wlr_keyboard->xkb_state, keycode, &syms);
|
group->wlr_group->keyboard.xkb_state, keycode, &syms);
|
||||||
|
|
||||||
int handled = 0;
|
int handled = 0;
|
||||||
uint32_t mods = wlr_keyboard_get_modifiers(kb->wlr_keyboard);
|
uint32_t mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard);
|
||||||
|
|
||||||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||||
|
|
||||||
|
|
@ -3384,21 +3444,23 @@ keypress(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* On _press_ if there is no active screen locker,
|
/* On _press_ if there is no active screen locker,
|
||||||
* attempt to process a compositor keybinding. */
|
* attempt to process a compositor keybinding. */
|
||||||
if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED)
|
if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||||
for (i = 0; i < nsyms; i++)
|
for (i = 0; i < nsyms; i++)
|
||||||
handled = keybinding(mods, syms[i]) || handled;
|
handled = keybinding(mods, syms[i]) || handled;
|
||||||
|
}
|
||||||
|
|
||||||
if (handled && kb->wlr_keyboard->repeat_info.delay > 0) {
|
if (handled && group->wlr_group->keyboard.repeat_info.delay > 0) {
|
||||||
kb->mods = mods;
|
group->mods = mods;
|
||||||
kb->keysyms = syms;
|
group->keysyms = syms;
|
||||||
kb->nsyms = nsyms;
|
group->nsyms = nsyms;
|
||||||
wl_event_source_timer_update(kb->key_repeat_source,
|
wl_event_source_timer_update(group->key_repeat_source,
|
||||||
kb->wlr_keyboard->repeat_info.delay);
|
group->wlr_group->keyboard.repeat_info.delay);
|
||||||
} else {
|
} else {
|
||||||
kb->nsyms = 0;
|
group->nsyms = 0;
|
||||||
wl_event_source_timer_update(kb->key_repeat_source, 0);
|
wl_event_source_timer_update(group->key_repeat_source, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handled)
|
if (handled)
|
||||||
|
|
@ -3406,46 +3468,42 @@ keypress(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
#ifdef IM
|
#ifdef IM
|
||||||
/* if there is a keyboard grab, we send the key there */
|
/* if there is a keyboard grab, we send the key there */
|
||||||
struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(kb);
|
struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(group);
|
||||||
if (kb_grab) {
|
if (kb_grab) {
|
||||||
wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab, kb->wlr_keyboard);
|
wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab,&(group->wlr_group->keyboard));
|
||||||
wlr_input_method_keyboard_grab_v2_send_key(kb_grab, event->time_msec,
|
wlr_input_method_keyboard_grab_v2_send_key(kb_grab,event->time_msec, event->keycode, event->state);
|
||||||
event->keycode, event->state);
|
wlr_log(WLR_DEBUG, "keypress send to IM:%u mods %u state %u",event->keycode, mods,event->state);
|
||||||
wlr_log(WLR_DEBUG, "keypress send to IM:%u mods %u state %u",
|
|
||||||
event->keycode, mods, event->state);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard);
|
||||||
/* Pass unhandled keycodes along to the client. */
|
/* Pass unhandled keycodes along to the client. */
|
||||||
wlr_seat_set_keyboard(seat, kb->wlr_keyboard);
|
wlr_seat_keyboard_notify_key(seat, event->time_msec,
|
||||||
wlr_seat_keyboard_notify_key(seat, event->time_msec, event->keycode,
|
event->keycode, event->state);
|
||||||
event->state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void // 17
|
|
||||||
keypressmod(struct wl_listener *listener, void *data) {
|
void
|
||||||
|
keypressmod(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
/* This event is raised when a modifier key, such as shift or alt, is
|
/* This event is raised when a modifier key, such as shift or alt, is
|
||||||
* pressed. We simply communicate this to the client. */
|
* pressed. We simply communicate this to the client. */
|
||||||
Keyboard *kb = wl_container_of(listener, kb, modifiers);
|
KeyboardGroup *group = wl_container_of(listener, group, modifiers);
|
||||||
|
|
||||||
#ifdef IM
|
#ifdef IM
|
||||||
struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(kb);
|
struct wlr_input_method_keyboard_grab_v2 *kb_grab = keyboard_get_im_grab(group);
|
||||||
if (kb_grab) {
|
if (kb_grab) {
|
||||||
wlr_input_method_keyboard_grab_v2_send_modifiers(
|
wlr_input_method_keyboard_grab_v2_send_modifiers(kb_grab,
|
||||||
kb_grab, &kb->wlr_keyboard->modifiers);
|
&group->wlr_group->keyboard.modifiers);
|
||||||
wlr_log(WLR_DEBUG, "keypressmod send to IM");
|
wlr_log(WLR_DEBUG, "keypressmod send to IM");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*
|
wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard);
|
||||||
* A seat can only have one keyboard, but this is a limitation of the
|
|
||||||
* Wayland protocol - not wlroots. We assign all connected keyboards to the
|
|
||||||
* same seat. You can swap out the underlying wlr_keyboard like this and
|
|
||||||
* wlr_seat handles this transparently.
|
|
||||||
*/
|
|
||||||
wlr_seat_set_keyboard(seat, kb->wlr_keyboard);
|
|
||||||
/* Send modifiers to the client. */
|
/* Send modifiers to the client. */
|
||||||
wlr_seat_keyboard_notify_modifiers(seat, &kb->wlr_keyboard->modifiers);
|
wlr_seat_keyboard_notify_modifiers(seat,
|
||||||
|
&group->wlr_group->keyboard.modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool scene_node_snapshot(struct wlr_scene_node *node, int lx, int ly,
|
static bool scene_node_snapshot(struct wlr_scene_node *node, int lx, int ly,
|
||||||
|
|
@ -3981,29 +4039,23 @@ void outputmgrtest(struct wl_listener *listener, void *data) {
|
||||||
outputmgrapplyortest(config, 1);
|
outputmgrapplyortest(config, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void // 17
|
void
|
||||||
pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
|
pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
|
||||||
uint32_t time) {
|
uint32_t time)
|
||||||
|
{
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
int internal_call = !time;
|
|
||||||
|
|
||||||
if (surface != seat->pointer_state.focused_surface && sloppyfocus && time &&
|
if (surface != seat->pointer_state.focused_surface &&
|
||||||
c && !client_is_unmanaged(c))
|
sloppyfocus && time && c && !client_is_unmanaged(c))
|
||||||
focusclient(c, 0);
|
focusclient(c, 0);
|
||||||
|
|
||||||
/* If surface is NULL, try use the focused client surface to set pointer foucs
|
/* If surface is NULL, clear pointer focus */
|
||||||
*/
|
|
||||||
if (time == 0 && !surface && selmon && selmon->sel) {
|
|
||||||
surface = client_surface(selmon->sel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If surface is still NULL, clear pointer focus */
|
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
wlr_seat_pointer_notify_clear_focus(seat);
|
wlr_seat_pointer_notify_clear_focus(seat);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (internal_call) {
|
if (!time) {
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
time = now.tv_sec * 1000 + now.tv_nsec / 1000000;
|
time = now.tv_sec * 1000 + now.tv_nsec / 1000000;
|
||||||
}
|
}
|
||||||
|
|
@ -4254,8 +4306,8 @@ void set_open_animaiton(Client *c, struct wlr_box geo) {
|
||||||
int vertical, vertical_value;
|
int vertical, vertical_value;
|
||||||
int special_direction;
|
int special_direction;
|
||||||
int center_x, center_y;
|
int center_x, center_y;
|
||||||
if (strcmp(animation_type, "zoom") == 0 ||
|
if (strcmp(animation_type_open, "zoom") == 0 ||
|
||||||
(c->animation_type && strcmp(c->animation_type, "zoom") == 0)) {
|
(c->animation_type_open && strcmp(c->animation_type_open, "zoom") == 0)) {
|
||||||
c->animainit_geom.width = geo.width * zoom_initial_ratio;
|
c->animainit_geom.width = geo.width * zoom_initial_ratio;
|
||||||
c->animainit_geom.height = geo.height * zoom_initial_ratio;
|
c->animainit_geom.height = geo.height * zoom_initial_ratio;
|
||||||
c->animainit_geom.x = geo.x + (geo.width - c->animainit_geom.width) / 2;
|
c->animainit_geom.x = geo.x + (geo.width - c->animainit_geom.width) / 2;
|
||||||
|
|
@ -4746,8 +4798,9 @@ void setmon(Client *c, Monitor *m, uint32_t newtags) {
|
||||||
focusclient(focustop(selmon), 1);
|
focusclient(focustop(selmon), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void // 17
|
void
|
||||||
setpsel(struct wl_listener *listener, void *data) {
|
setpsel(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
/* This event is raised by the seat when a client wants to set the selection,
|
/* This event is raised by the seat when a client wants to set the selection,
|
||||||
* usually when the user copies something. wlroots allows compositors to
|
* usually when the user copies something. wlroots allows compositors to
|
||||||
* ignore such requests if they so choose, but in dwl we always honor
|
* ignore such requests if they so choose, but in dwl we always honor
|
||||||
|
|
@ -4756,8 +4809,9 @@ setpsel(struct wl_listener *listener, void *data) {
|
||||||
wlr_seat_set_primary_selection(seat, event->source, event->serial);
|
wlr_seat_set_primary_selection(seat, event->source, event->serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
void // 17
|
void
|
||||||
setsel(struct wl_listener *listener, void *data) {
|
setsel(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
/* This event is raised by the seat when a client wants to set the selection,
|
/* This event is raised by the seat when a client wants to set the selection,
|
||||||
* usually when the user copies something. wlroots allows compositors to
|
* usually when the user copies something. wlroots allows compositors to
|
||||||
* ignore such requests if they so choose, but in dwl we always honor
|
* ignore such requests if they so choose, but in dwl we always honor
|
||||||
|
|
@ -5107,6 +5161,9 @@ void setup(void) {
|
||||||
wl_signal_add(&seat->events.request_start_drag, &request_start_drag);
|
wl_signal_add(&seat->events.request_start_drag, &request_start_drag);
|
||||||
wl_signal_add(&seat->events.start_drag, &start_drag);
|
wl_signal_add(&seat->events.start_drag, &start_drag);
|
||||||
|
|
||||||
|
kb_group = createkeyboardgroup();
|
||||||
|
wl_list_init(&kb_group->destroy.link);
|
||||||
|
|
||||||
output_mgr = wlr_output_manager_v1_create(dpy);
|
output_mgr = wlr_output_manager_v1_create(dpy);
|
||||||
wl_signal_add(&output_mgr->events.apply, &output_mgr_apply);
|
wl_signal_add(&output_mgr->events.apply, &output_mgr_apply);
|
||||||
wl_signal_add(&output_mgr->events.test, &output_mgr_test);
|
wl_signal_add(&output_mgr->events.test, &output_mgr_test);
|
||||||
|
|
@ -5922,7 +5979,7 @@ void init_fadeout_client(Client *c) {
|
||||||
fadeout_cient->geom = fadeout_cient->current = fadeout_cient->animainit_geom =
|
fadeout_cient->geom = fadeout_cient->current = fadeout_cient->animainit_geom =
|
||||||
fadeout_cient->animation.initial = c->animation.current;
|
fadeout_cient->animation.initial = c->animation.current;
|
||||||
fadeout_cient->mon = c->mon;
|
fadeout_cient->mon = c->mon;
|
||||||
fadeout_cient->animation_type = c->animation_type;
|
fadeout_cient->animation_type_close = c->animation_type_close;
|
||||||
fadeout_cient->animation.action = CLOSE;
|
fadeout_cient->animation.action = CLOSE;
|
||||||
fadeout_cient->bw = c->bw;
|
fadeout_cient->bw = c->bw;
|
||||||
|
|
||||||
|
|
@ -5931,8 +5988,8 @@ void init_fadeout_client(Client *c) {
|
||||||
|
|
||||||
fadeout_cient->animation.initial.x = 0;
|
fadeout_cient->animation.initial.x = 0;
|
||||||
fadeout_cient->animation.initial.y = 0;
|
fadeout_cient->animation.initial.y = 0;
|
||||||
if ((c->animation_type && strcmp(c->animation_type, "slide") == 0) ||
|
if ((c->animation_type_close && strcmp(c->animation_type_close, "slide") == 0) ||
|
||||||
(!c->animation_type && strcmp(animation_type, "slide") == 0)) {
|
(!c->animation_type_close && strcmp(animation_type_close, "slide") == 0)) {
|
||||||
fadeout_cient->current.y =
|
fadeout_cient->current.y =
|
||||||
c->geom.y + c->geom.height / 2 > c->mon->m.y + c->mon->m.height / 2
|
c->geom.y + c->geom.height / 2 > c->mon->m.y + c->mon->m.height / 2
|
||||||
? c->mon->m.height -
|
? c->mon->m.height -
|
||||||
|
|
@ -5941,11 +5998,11 @@ void init_fadeout_client(Client *c) {
|
||||||
fadeout_cient->current.x = 0; // x无偏差,垂直划出
|
fadeout_cient->current.x = 0; // x无偏差,垂直划出
|
||||||
} else {
|
} else {
|
||||||
fadeout_cient->current.y =
|
fadeout_cient->current.y =
|
||||||
(c->geom.height - c->geom.height * zoom_initial_ratio) / 2;
|
(fadeout_cient->geom.height - fadeout_cient->geom.height * zoom_initial_ratio) / 2;
|
||||||
fadeout_cient->current.x =
|
fadeout_cient->current.x =
|
||||||
(c->geom.width - c->geom.width * zoom_initial_ratio) / 2;
|
(fadeout_cient->geom.width - fadeout_cient->geom.width * zoom_initial_ratio) / 2;
|
||||||
fadeout_cient->current.width = c->geom.width * zoom_initial_ratio;
|
fadeout_cient->current.width = fadeout_cient->geom.width * zoom_initial_ratio;
|
||||||
fadeout_cient->current.height = c->geom.height * zoom_initial_ratio;
|
fadeout_cient->current.height = fadeout_cient->geom.height * zoom_initial_ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
fadeout_cient->animation.passed_frames = 0;
|
fadeout_cient->animation.passed_frames = 0;
|
||||||
|
|
@ -5956,6 +6013,7 @@ void init_fadeout_client(Client *c) {
|
||||||
wl_list_insert(&fadeout_clients, &fadeout_cient->fadeout_link);
|
wl_list_insert(&fadeout_clients, &fadeout_cient->fadeout_link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void unmapnotify(struct wl_listener *listener, void *data) {
|
void unmapnotify(struct wl_listener *listener, void *data) {
|
||||||
/* Called when the surface is unmapped, and should no longer be shown. */
|
/* Called when the surface is unmapped, and should no longer be shown. */
|
||||||
Client *c = wl_container_of(listener, c, unmap);
|
Client *c = wl_container_of(listener, c, unmap);
|
||||||
|
|
@ -6375,9 +6433,18 @@ void tagtoright(const Arg *arg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtualkeyboard(struct wl_listener *listener, void *data) {
|
void
|
||||||
struct wlr_virtual_keyboard_v1 *keyboard = data;
|
virtualkeyboard(struct wl_listener *listener, void *data)
|
||||||
createkeyboard(&keyboard->keyboard);
|
{
|
||||||
|
struct wlr_virtual_keyboard_v1 *kb = data;
|
||||||
|
/* virtual keyboards shouldn't share keyboard group */
|
||||||
|
KeyboardGroup *group = createkeyboardgroup();
|
||||||
|
/* Set the keymap to match the group keymap */
|
||||||
|
wlr_keyboard_set_keymap(&kb->keyboard, group->wlr_group->keyboard.keymap);
|
||||||
|
LISTEN(&kb->keyboard.base.events.destroy, &group->destroy, destroykeyboardgroup);
|
||||||
|
|
||||||
|
/* Add the new keyboard to the group */
|
||||||
|
wlr_keyboard_group_add_keyboard(group->wlr_group, &kb->keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
void warp_cursor(const Client *c) {
|
void warp_cursor(const Client *c) {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ typedef struct {
|
||||||
int isfloating;
|
int isfloating;
|
||||||
int isfullscreen;
|
int isfullscreen;
|
||||||
float scroller_proportion;
|
float scroller_proportion;
|
||||||
const char *animation_type;
|
const char *animation_type_open;
|
||||||
|
const char *animation_type_close;
|
||||||
int isnoborder;
|
int isnoborder;
|
||||||
int monitor;
|
int monitor;
|
||||||
int width;
|
int width;
|
||||||
|
|
@ -71,7 +72,8 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int animations;
|
int animations;
|
||||||
char animation_type[10];
|
char animation_type_open[10];
|
||||||
|
char animation_type_close[10];
|
||||||
char animation_fade_in;
|
char animation_fade_in;
|
||||||
float zoom_initial_ratio;
|
float zoom_initial_ratio;
|
||||||
float fadein_begin_opacity;
|
float fadein_begin_opacity;
|
||||||
|
|
@ -481,8 +483,10 @@ void parse_config_line(Config *config, const char *line) {
|
||||||
|
|
||||||
if (strcmp(key, "animations") == 0) {
|
if (strcmp(key, "animations") == 0) {
|
||||||
config->animations = atoi(value);
|
config->animations = atoi(value);
|
||||||
} else if (strcmp(key, "animation_type") == 0) {
|
} else if (strcmp(key, "animation_type_open") == 0) {
|
||||||
strncpy(config->animation_type, value, sizeof(config->animation_type));
|
strncpy(config->animation_type_open, value, sizeof(config->animation_type_open));
|
||||||
|
} else if (strcmp(key, "animation_type_close") == 0) {
|
||||||
|
strncpy(config->animation_type_close, value, sizeof(config->animation_type_close));
|
||||||
} else if (strcmp(key, "animation_fade_in") == 0) {
|
} else if (strcmp(key, "animation_fade_in") == 0) {
|
||||||
config->animation_fade_in = atoi(value);
|
config->animation_fade_in = atoi(value);
|
||||||
} else if (strcmp(key, "zoom_initial_ratio") == 0) {
|
} else if (strcmp(key, "zoom_initial_ratio") == 0) {
|
||||||
|
|
@ -792,7 +796,8 @@ void parse_config_line(Config *config, const char *line) {
|
||||||
rule->monitor = -1;
|
rule->monitor = -1;
|
||||||
rule->width = -1;
|
rule->width = -1;
|
||||||
rule->height = -1;
|
rule->height = -1;
|
||||||
rule->animation_type = NULL;
|
rule->animation_type_open = NULL;
|
||||||
|
rule->animation_type_close = NULL;
|
||||||
rule->scroller_proportion = -1;
|
rule->scroller_proportion = -1;
|
||||||
rule->id = NULL;
|
rule->id = NULL;
|
||||||
rule->title = NULL;
|
rule->title = NULL;
|
||||||
|
|
@ -812,8 +817,10 @@ void parse_config_line(Config *config, const char *line) {
|
||||||
rule->title = strdup(val);
|
rule->title = strdup(val);
|
||||||
} else if (strcmp(key, "appid") == 0) {
|
} else if (strcmp(key, "appid") == 0) {
|
||||||
rule->id = strdup(val);
|
rule->id = strdup(val);
|
||||||
} else if (strcmp(key, "animation_type") == 0) {
|
} else if (strcmp(key, "animation_type_open") == 0) {
|
||||||
rule->animation_type = strdup(val);
|
rule->animation_type_open = strdup(val);
|
||||||
|
} else if (strcmp(key, "animation_type_close") == 0) {
|
||||||
|
rule->animation_type_close = strdup(val);
|
||||||
} else if (strcmp(key, "tags") == 0) {
|
} else if (strcmp(key, "tags") == 0) {
|
||||||
rule->tags = 1 << (atoi(val) - 1);
|
rule->tags = 1 << (atoi(val) - 1);
|
||||||
} else if (strcmp(key, "monitor") == 0) {
|
} else if (strcmp(key, "monitor") == 0) {
|
||||||
|
|
@ -1029,8 +1036,10 @@ void free_config(void) {
|
||||||
free((void *)rule->id);
|
free((void *)rule->id);
|
||||||
if (rule->title)
|
if (rule->title)
|
||||||
free((void *)rule->title);
|
free((void *)rule->title);
|
||||||
if (rule->animation_type)
|
if (rule->animation_type_open)
|
||||||
free((void *)rule->animation_type);
|
free((void *)rule->animation_type_open);
|
||||||
|
if (rule->animation_type_close)
|
||||||
|
free((void *)rule->animation_type_close);
|
||||||
}
|
}
|
||||||
free(config.window_rules);
|
free(config.window_rules);
|
||||||
|
|
||||||
|
|
@ -1076,7 +1085,8 @@ void free_config(void) {
|
||||||
|
|
||||||
void override_config(void) {
|
void override_config(void) {
|
||||||
animations = config.animations;
|
animations = config.animations;
|
||||||
animation_type = config.animation_type;
|
animation_type_open = config.animation_type_open;
|
||||||
|
animation_type_close = config.animation_type_close;
|
||||||
animation_fade_in = config.animation_fade_in;
|
animation_fade_in = config.animation_fade_in;
|
||||||
zoom_initial_ratio = config.zoom_initial_ratio;
|
zoom_initial_ratio = config.zoom_initial_ratio;
|
||||||
fadein_begin_opacity = config.fadein_begin_opacity;
|
fadein_begin_opacity = config.fadein_begin_opacity;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
((hex >> 8) & 0xFF) / 255.0f, (hex & 0xFF) / 255.0f}
|
((hex >> 8) & 0xFF) / 255.0f, (hex & 0xFF) / 255.0f}
|
||||||
|
|
||||||
/* animaion */
|
/* animaion */
|
||||||
char *animation_type = "slide"; // 是否启用动画 //slide,zoom
|
char *animation_type_open = "slide"; // 是否启用动画 //slide,zoom
|
||||||
|
char *animation_type_close = "slide"; // 是否启用动画 //slide,zoom
|
||||||
int animations = 1; // 是否启用动画
|
int animations = 1; // 是否启用动画
|
||||||
char animation_fade_in = 1; // Enable animation fade in
|
char animation_fade_in = 1; // Enable animation fade in
|
||||||
float zoom_initial_ratio = 0.5; // 动画起始窗口比例
|
float zoom_initial_ratio = 0.5; // 动画起始窗口比例
|
||||||
|
|
@ -30,6 +31,7 @@ unsigned int default_nmaster = 1; // 默认master数量
|
||||||
/* logging */
|
/* logging */
|
||||||
int log_level = WLR_ERROR;
|
int log_level = WLR_ERROR;
|
||||||
unsigned int numlockon = 1; // 是否打开右边小键盘
|
unsigned int numlockon = 1; // 是否打开右边小键盘
|
||||||
|
unsigned int capslock = 0; // 是否打开大写锁定
|
||||||
|
|
||||||
unsigned int ov_tab_mode = 0; // alt tab切换模式
|
unsigned int ov_tab_mode = 0; // alt tab切换模式
|
||||||
unsigned int hotarea_size = 10; // 热区大小,10x10
|
unsigned int hotarea_size = 10; // 热区大小,10x10
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue