Merge branch 'master' into feature/wlr-seat-touch
This commit is contained in:
commit
584ff1df4c
14
README.md
14
README.md
|
@ -33,3 +33,17 @@ Run these commands:
|
|||
ninja -C build
|
||||
|
||||
(On FreeBSD, you need to pass an extra flag to prevent a linking error: `meson build -D b_lundef=false`)
|
||||
|
||||
## Running the Reference Compositor
|
||||
|
||||
wlroots comes with a reference compositor called rootston that demonstrates the
|
||||
features of the library.
|
||||
|
||||
After building, run rootston from a terminal or VT with:
|
||||
|
||||
./build/rootston/rootston
|
||||
|
||||
Now you can run windows in the compositor from the command line or by
|
||||
configuring bindings in your
|
||||
[`rootston.ini`](https://github.com/swaywm/wlroots/blob/master/rootston/rootston.ini.example)
|
||||
file.
|
||||
|
|
|
@ -66,10 +66,11 @@ static void handle_device_added(struct wlr_libinput_backend *backend,
|
|||
int product = libinput_device_get_id_product(libinput_dev);
|
||||
const char *name = libinput_device_get_name(libinput_dev);
|
||||
struct wl_list *wlr_devices = calloc(1, sizeof(struct wl_list));
|
||||
wl_list_init(wlr_devices);
|
||||
if (!wlr_devices) {
|
||||
goto fail;
|
||||
wlr_log(L_ERROR, "Allocation failed");
|
||||
return;
|
||||
}
|
||||
wl_list_init(wlr_devices);
|
||||
wlr_log(L_DEBUG, "Added %s [%d:%d]", name, vendor, product);
|
||||
|
||||
if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_KEYBOARD)) {
|
||||
|
|
|
@ -249,7 +249,7 @@ static size_t explicit_find_gpus(struct wlr_session *session,
|
|||
}
|
||||
} while ((ptr = strtok_r(NULL, ":", &save)));
|
||||
|
||||
free(ptr);
|
||||
free(gpus);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,10 +12,15 @@
|
|||
#include "backend/wayland.h"
|
||||
#include "xdg-shell-unstable-v6-client-protocol.h"
|
||||
|
||||
|
||||
static int dispatch_events(int fd, uint32_t mask, void *data) {
|
||||
struct wlr_wl_backend *backend = data;
|
||||
int count = 0;
|
||||
|
||||
if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
|
||||
wl_display_terminate(backend->local_display);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mask & WL_EVENT_READABLE) {
|
||||
count = wl_display_dispatch(backend->remote_display);
|
||||
}
|
||||
|
@ -36,7 +41,7 @@ static bool wlr_wl_backend_start(struct wlr_backend *_backend) {
|
|||
wlr_log(L_INFO, "Initializating wayland backend");
|
||||
|
||||
wlr_wl_registry_poll(backend);
|
||||
if (!(backend->compositor) || (!(backend->shell))) {
|
||||
if (!backend->compositor || !backend->shell) {
|
||||
wlr_log_errno(L_ERROR, "Could not obtain retrieve required globals");
|
||||
return false;
|
||||
}
|
||||
|
@ -49,10 +54,9 @@ static bool wlr_wl_backend_start(struct wlr_backend *_backend) {
|
|||
|
||||
struct wl_event_loop *loop = wl_display_get_event_loop(backend->local_display);
|
||||
int fd = wl_display_get_fd(backend->remote_display);
|
||||
int events = WL_EVENT_READABLE | WL_EVENT_ERROR |
|
||||
WL_EVENT_HANGUP;
|
||||
int events = WL_EVENT_READABLE | WL_EVENT_ERROR | WL_EVENT_HANGUP;
|
||||
backend->remote_display_src = wl_event_loop_add_fd(loop, fd, events,
|
||||
dispatch_events, backend);
|
||||
dispatch_events, backend);
|
||||
wl_event_source_check(backend->remote_display_src);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -155,9 +155,14 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e
|
|||
|
||||
static int x11_event(int fd, uint32_t mask, void *data) {
|
||||
struct wlr_x11_backend *x11 = data;
|
||||
|
||||
if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
|
||||
wl_display_terminate(x11->wl_display);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xcb_generic_event_t *e;
|
||||
bool quit = false;
|
||||
|
||||
while (!quit && (e = xcb_poll_for_event(x11->xcb_conn))) {
|
||||
quit = handle_x11_event(x11, e);
|
||||
free(e);
|
||||
|
@ -205,7 +210,8 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
|
|||
|
||||
int fd = xcb_get_file_descriptor(x11->xcb_conn);
|
||||
struct wl_event_loop *ev = wl_display_get_event_loop(display);
|
||||
x11->event_source = wl_event_loop_add_fd(ev, fd, WL_EVENT_READABLE, x11_event, x11);
|
||||
int events = WL_EVENT_READABLE | WL_EVENT_ERROR | WL_EVENT_HANGUP;
|
||||
x11->event_source = wl_event_loop_add_fd(ev, fd, events, x11_event, x11);
|
||||
if (!x11->event_source) {
|
||||
wlr_log(L_ERROR, "Could not create event source");
|
||||
goto error_x11;
|
||||
|
|
|
@ -16,7 +16,8 @@ struct roots_keyboard {
|
|||
struct wl_listener keyboard_key;
|
||||
struct wl_listener keyboard_modifiers;
|
||||
|
||||
xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP];
|
||||
xkb_keysym_t pressed_keysyms_translated[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP];
|
||||
xkb_keysym_t pressed_keysyms_raw[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP];
|
||||
};
|
||||
|
||||
struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device,
|
||||
|
|
|
@ -405,7 +405,7 @@ void roots_config_destroy(struct roots_config *config) {
|
|||
}
|
||||
|
||||
struct roots_keyboard_config *kc, *ktmp = NULL;
|
||||
wl_list_for_each_safe(kc, ktmp, &config->bindings, link) {
|
||||
wl_list_for_each_safe(kc, ktmp, &config->keyboards, link) {
|
||||
free(kc->name);
|
||||
free(kc->rules);
|
||||
free(kc->model);
|
||||
|
|
|
@ -18,9 +18,9 @@ struct roots_cursor *roots_cursor_create(struct roots_seat *seat) {
|
|||
}
|
||||
cursor->cursor = wlr_cursor_create();
|
||||
if (!cursor->cursor) {
|
||||
free(cursor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,16 +13,76 @@
|
|||
#include "rootston/seat.h"
|
||||
#include "rootston/keyboard.h"
|
||||
|
||||
static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard,
|
||||
static ssize_t pressed_keysyms_index(xkb_keysym_t *pressed_keysyms,
|
||||
xkb_keysym_t keysym) {
|
||||
for (size_t i = 0; i < ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP; i++) {
|
||||
if (keyboard->pressed_keysyms[i] == keysym) {
|
||||
for (size_t i = 0; i < ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP; ++i) {
|
||||
if (pressed_keysyms[i] == keysym) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static size_t pressed_keysyms_length(xkb_keysym_t *pressed_keysyms) {
|
||||
size_t n = 0;
|
||||
for (size_t i = 0; i < ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP; ++i) {
|
||||
if (pressed_keysyms[i] != XKB_KEY_NoSymbol) {
|
||||
++n;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static void pressed_keysyms_add(xkb_keysym_t *pressed_keysyms,
|
||||
xkb_keysym_t keysym) {
|
||||
ssize_t i = pressed_keysyms_index(pressed_keysyms, keysym);
|
||||
if (i < 0) {
|
||||
i = pressed_keysyms_index(pressed_keysyms, XKB_KEY_NoSymbol);
|
||||
if (i >= 0) {
|
||||
pressed_keysyms[i] = keysym;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pressed_keysyms_remove(xkb_keysym_t *pressed_keysyms,
|
||||
xkb_keysym_t keysym) {
|
||||
ssize_t i = pressed_keysyms_index(pressed_keysyms, keysym);
|
||||
if (i >= 0) {
|
||||
pressed_keysyms[i] = XKB_KEY_NoSymbol;
|
||||
}
|
||||
}
|
||||
|
||||
static bool keysym_is_modifier(xkb_keysym_t keysym) {
|
||||
switch (keysym) {
|
||||
case XKB_KEY_Shift_L: case XKB_KEY_Shift_R:
|
||||
case XKB_KEY_Control_L: case XKB_KEY_Control_R:
|
||||
case XKB_KEY_Caps_Lock:
|
||||
case XKB_KEY_Shift_Lock:
|
||||
case XKB_KEY_Meta_L: case XKB_KEY_Meta_R:
|
||||
case XKB_KEY_Alt_L: case XKB_KEY_Alt_R:
|
||||
case XKB_KEY_Super_L: case XKB_KEY_Super_R:
|
||||
case XKB_KEY_Hyper_L: case XKB_KEY_Hyper_R:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void pressed_keysyms_update(xkb_keysym_t *pressed_keysyms,
|
||||
const xkb_keysym_t *keysyms, size_t keysyms_len,
|
||||
enum wlr_key_state state) {
|
||||
for (size_t i = 0; i < keysyms_len; ++i) {
|
||||
if (keysym_is_modifier(keysyms[i])) {
|
||||
continue;
|
||||
}
|
||||
if (state == WLR_KEY_PRESSED) {
|
||||
pressed_keysyms_add(pressed_keysyms, keysyms[i]);
|
||||
} else { // WLR_KEY_RELEASED
|
||||
pressed_keysyms_remove(pressed_keysyms, keysyms[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char *exec_prefix = "exec ";
|
||||
|
||||
static void keyboard_binding_execute(struct roots_keyboard *keyboard,
|
||||
|
@ -56,21 +116,14 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard,
|
|||
}
|
||||
|
||||
/**
|
||||
* Process a keypress from the keyboard.
|
||||
* Execute a built-in, hardcoded compositor binding. These are triggered from a
|
||||
* single keysym.
|
||||
*
|
||||
* Returns true if the keysym was handled by a binding and false if the event
|
||||
* should be propagated to clients.
|
||||
*/
|
||||
static bool keyboard_keysym_press(struct roots_keyboard *keyboard,
|
||||
static bool keyboard_execute_compositor_binding(struct roots_keyboard *keyboard,
|
||||
xkb_keysym_t keysym) {
|
||||
ssize_t i = keyboard_pressed_keysym_index(keyboard, keysym);
|
||||
if (i < 0) {
|
||||
i = keyboard_pressed_keysym_index(keyboard, XKB_KEY_NoSymbol);
|
||||
if (i >= 0) {
|
||||
keyboard->pressed_keysyms[i] = keysym;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym >= XKB_KEY_XF86Switch_VT_1 &&
|
||||
keysym <= XKB_KEY_XF86Switch_VT_12) {
|
||||
struct roots_server *server = keyboard->input->server;
|
||||
|
@ -90,17 +143,37 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard,
|
|||
wlr_seat_keyboard_end_grab(keyboard->seat->seat);
|
||||
}
|
||||
|
||||
uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute keyboard bindings. These include compositor bindings and user-defined
|
||||
* bindings.
|
||||
*
|
||||
* Returns true if the keysym was handled by a binding and false if the event
|
||||
* should be propagated to clients.
|
||||
*/
|
||||
static bool keyboard_execute_binding(struct roots_keyboard *keyboard,
|
||||
xkb_keysym_t *pressed_keysyms, uint32_t modifiers,
|
||||
const xkb_keysym_t *keysyms, size_t keysyms_len) {
|
||||
for (size_t i = 0; i < keysyms_len; ++i) {
|
||||
if (keyboard_execute_compositor_binding(keyboard, keysyms[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// User-defined bindings
|
||||
size_t n = pressed_keysyms_length(pressed_keysyms);
|
||||
struct wl_list *bindings = &keyboard->input->server->config->bindings;
|
||||
struct roots_binding_config *bc;
|
||||
wl_list_for_each(bc, bindings, link) {
|
||||
if (modifiers ^ bc->modifiers) {
|
||||
if (modifiers ^ bc->modifiers || n != bc->keysyms_len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < bc->keysyms_len; i++) {
|
||||
ssize_t j = keyboard_pressed_keysym_index(keyboard, bc->keysyms[i]);
|
||||
ssize_t j = pressed_keysyms_index(pressed_keysyms, bc->keysyms[i]);
|
||||
if (j < 0) {
|
||||
ok = false;
|
||||
break;
|
||||
|
@ -116,85 +189,75 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard,
|
|||
return false;
|
||||
}
|
||||
|
||||
static void keyboard_keysym_release(struct roots_keyboard *keyboard,
|
||||
xkb_keysym_t keysym) {
|
||||
ssize_t i = keyboard_pressed_keysym_index(keyboard, keysym);
|
||||
if (i >= 0) {
|
||||
keyboard->pressed_keysyms[i] = XKB_KEY_NoSymbol;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Process keypresses from the keyboard as xkb sees them.
|
||||
* Get keysyms and modifiers from the keyboard as xkb sees them.
|
||||
*
|
||||
* This uses the xkb keysyms translation based on pressed modifiers and clears
|
||||
* the consumed modifiers from the list of modifiers passed to keybind
|
||||
* detection.
|
||||
*
|
||||
* (On US layout) this will trigger: [Alt]+[at]
|
||||
* On US layout, pressing Alt+Shift+2 will trigger Alt+@.
|
||||
*/
|
||||
static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard,
|
||||
uint32_t keycode, enum wlr_key_state state) {
|
||||
uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard);
|
||||
const xkb_keysym_t *syms;
|
||||
int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state,
|
||||
keycode, &syms);
|
||||
uint32_t consumed = xkb_state_key_get_consumed_mods2(
|
||||
static size_t keyboard_keysyms_translated(struct roots_keyboard *keyboard,
|
||||
xkb_keycode_t keycode, const xkb_keysym_t **keysyms,
|
||||
uint32_t *modifiers) {
|
||||
*modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard);
|
||||
xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods2(
|
||||
keyboard->device->keyboard->xkb_state, keycode, XKB_CONSUMED_MODE_XKB);
|
||||
*modifiers = *modifiers & ~consumed;
|
||||
|
||||
modifiers = modifiers & ~consumed;
|
||||
|
||||
bool handled = false;
|
||||
for (int i = 0; i < syms_len; i++) {
|
||||
if (state) {
|
||||
bool keysym_handled =
|
||||
keyboard_keysym_press(keyboard, syms[i]);
|
||||
handled = handled || keysym_handled;
|
||||
} else { // WLR_KEY_RELEASED
|
||||
keyboard_keysym_release(keyboard, syms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
return xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state,
|
||||
keycode, keysyms);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process keypresses from the keyboard as if modifiers didn't change keysyms.
|
||||
* Get keysyms and modifiers from the keyboard as if modifiers didn't change
|
||||
* keysyms.
|
||||
*
|
||||
* This avoids the xkb keysym translation based on modifiers considered pressed
|
||||
* in the state and uses the list of modifiers saved on the rootston side.
|
||||
* in the state.
|
||||
*
|
||||
* This will trigger the keybind: [Alt]+[Shift]+2
|
||||
* This will trigger keybinds such as Alt+Shift+2.
|
||||
*/
|
||||
static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard,
|
||||
uint32_t keycode, enum wlr_key_state state) {
|
||||
const xkb_keysym_t *syms;
|
||||
static size_t keyboard_keysyms_raw(struct roots_keyboard *keyboard,
|
||||
xkb_keycode_t keycode, const xkb_keysym_t **keysyms,
|
||||
uint32_t *modifiers) {
|
||||
*modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard);
|
||||
|
||||
xkb_layout_index_t layout_index = xkb_state_key_get_layout(
|
||||
keyboard->device->keyboard->xkb_state, keycode);
|
||||
int syms_len = xkb_keymap_key_get_syms_by_level(
|
||||
keyboard->device->keyboard->keymap, keycode, layout_index, 0, &syms);
|
||||
|
||||
bool handled = false;
|
||||
for (int i = 0; i < syms_len; i++) {
|
||||
if (state) {
|
||||
bool keysym_handled = keyboard_keysym_press(keyboard, syms[i]);
|
||||
handled = handled || keysym_handled;
|
||||
} else { // WLR_KEY_RELEASED
|
||||
keyboard_keysym_release(keyboard, syms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
return xkb_keymap_key_get_syms_by_level(keyboard->device->keyboard->keymap,
|
||||
keycode, layout_index, 0, keysyms);
|
||||
}
|
||||
|
||||
void roots_keyboard_handle_key(struct roots_keyboard *keyboard,
|
||||
struct wlr_event_keyboard_key *event) {
|
||||
uint32_t keycode = event->keycode + 8;
|
||||
xkb_keycode_t keycode = event->keycode + 8;
|
||||
|
||||
bool handled = keyboard_keysyms_xkb(keyboard, keycode, event->state);
|
||||
bool handled = false;
|
||||
uint32_t modifiers;
|
||||
const xkb_keysym_t *keysyms;
|
||||
size_t keysyms_len;
|
||||
|
||||
if (!handled) {
|
||||
bool key_handled = keyboard_keysyms_simple(keyboard, keycode,
|
||||
event->state);
|
||||
handled = handled || key_handled;
|
||||
// Handle translated keysyms
|
||||
|
||||
keysyms_len = keyboard_keysyms_translated(keyboard, keycode, &keysyms,
|
||||
&modifiers);
|
||||
pressed_keysyms_update(keyboard->pressed_keysyms_translated, keysyms,
|
||||
keysyms_len, event->state);
|
||||
if (event->state == WLR_KEY_PRESSED) {
|
||||
handled = keyboard_execute_binding(keyboard,
|
||||
keyboard->pressed_keysyms_translated, modifiers, keysyms,
|
||||
keysyms_len);
|
||||
}
|
||||
|
||||
// Handle raw keysyms
|
||||
keysyms_len = keyboard_keysyms_raw(keyboard, keycode, &keysyms, &modifiers);
|
||||
pressed_keysyms_update(keyboard->pressed_keysyms_raw, keysyms, keysyms_len,
|
||||
event->state);
|
||||
if (event->state == WLR_KEY_PRESSED && !handled) {
|
||||
handled = keyboard_execute_binding(keyboard,
|
||||
keyboard->pressed_keysyms_raw, modifiers, keysyms, keysyms_len);
|
||||
}
|
||||
|
||||
if (!handled) {
|
||||
|
|
|
@ -40,6 +40,6 @@ meta-key = Logo
|
|||
# - "close" to close the current view
|
||||
# - "next_window" to cycle through windows
|
||||
[bindings]
|
||||
Logo+Shift+E = exit
|
||||
Logo+Shift+e = exit
|
||||
Logo+q = close
|
||||
Alt+Tab = next_window
|
||||
|
|
|
@ -274,7 +274,6 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) {
|
|||
seat->seat = wlr_seat_create(input->server->wl_display, name);
|
||||
if (!seat->seat) {
|
||||
free(seat);
|
||||
roots_cursor_destroy(seat->cursor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -713,7 +713,10 @@ static void data_device_start_drag(struct wl_client *client,
|
|||
|
||||
if (!seat_client_start_drag(seat_client, source, icon, origin, serial)) {
|
||||
wl_resource_post_no_memory(device_resource);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (source) {
|
||||
source->seat_client = seat_client;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,7 +105,10 @@ void wlr_keyboard_init(struct wlr_keyboard *kb,
|
|||
}
|
||||
|
||||
void wlr_keyboard_destroy(struct wlr_keyboard *kb) {
|
||||
if (kb && kb->impl && kb->impl->destroy) {
|
||||
if (kb == NULL) {
|
||||
return;
|
||||
}
|
||||
if (kb->impl && kb->impl->destroy) {
|
||||
kb->impl->destroy(kb);
|
||||
} else {
|
||||
wl_list_remove(&kb->events.key.listener_list);
|
||||
|
|
|
@ -29,8 +29,7 @@ static void wl_output_send_to_resource(struct wl_resource *resource) {
|
|||
if (version >= WL_OUTPUT_MODE_SINCE_VERSION) {
|
||||
struct wlr_output_mode *mode;
|
||||
wl_list_for_each(mode, &output->modes, link) {
|
||||
// TODO: mode->flags should just be preferred
|
||||
uint32_t flags = mode->flags;
|
||||
uint32_t flags = mode->flags & WL_OUTPUT_MODE_PREFERRED;
|
||||
if (output->current_mode == mode) {
|
||||
flags |= WL_OUTPUT_MODE_CURRENT;
|
||||
}
|
||||
|
@ -62,13 +61,17 @@ static void wlr_output_send_current_mode_to_resource(
|
|||
}
|
||||
if (output->current_mode != NULL) {
|
||||
struct wlr_output_mode *mode = output->current_mode;
|
||||
wl_output_send_mode(resource, mode->flags | WL_OUTPUT_MODE_CURRENT,
|
||||
uint32_t flags = mode->flags & WL_OUTPUT_MODE_PREFERRED;
|
||||
wl_output_send_mode(resource, flags | WL_OUTPUT_MODE_CURRENT,
|
||||
mode->width, mode->height, mode->refresh);
|
||||
} else {
|
||||
// Output has no mode, send the current width/height
|
||||
wl_output_send_mode(resource, WL_OUTPUT_MODE_CURRENT, output->width,
|
||||
output->height, 0);
|
||||
}
|
||||
if (version >= WL_OUTPUT_DONE_SINCE_VERSION) {
|
||||
wl_output_send_done(resource);
|
||||
}
|
||||
}
|
||||
|
||||
static void wl_output_destroy(struct wl_resource *resource) {
|
||||
|
@ -163,6 +166,9 @@ bool wlr_output_set_mode(struct wlr_output *output,
|
|||
|
||||
void wlr_output_update_size(struct wlr_output *output, int32_t width,
|
||||
int32_t height) {
|
||||
if (output->width == width && output->height == height) {
|
||||
return;
|
||||
}
|
||||
output->width = width;
|
||||
output->height = height;
|
||||
wlr_output_update_matrix(output);
|
||||
|
|
|
@ -85,6 +85,7 @@ static void screenshooter_shoot(struct wl_client *client,
|
|||
struct wlr_screenshot *screenshot =
|
||||
calloc(1, sizeof(struct wlr_screenshot));
|
||||
if (!screenshot) {
|
||||
free(pixels);
|
||||
wl_resource_post_no_memory(screenshooter_resource);
|
||||
return;
|
||||
}
|
||||
|
@ -96,6 +97,7 @@ static void screenshooter_shoot(struct wl_client *client,
|
|||
wl_resource_get_version(screenshooter_resource), id);
|
||||
if (screenshot->resource == NULL) {
|
||||
free(screenshot);
|
||||
free(pixels);
|
||||
wl_resource_post_no_memory(screenshooter_resource);
|
||||
return;
|
||||
}
|
||||
|
@ -109,6 +111,7 @@ static void screenshooter_shoot(struct wl_client *client,
|
|||
if (!state) {
|
||||
wl_resource_destroy(screenshot->resource);
|
||||
free(screenshot);
|
||||
free(pixels);
|
||||
wl_resource_post_no_memory(screenshooter_resource);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -347,7 +347,7 @@ static void shell_surface_protocol_set_popup(struct wl_client *client,
|
|||
transient_state->flags = flags;
|
||||
|
||||
struct wlr_wl_shell_surface_popup_state *popup_state =
|
||||
calloc(1, sizeof(struct wlr_wl_shell_surface_transient_state));
|
||||
calloc(1, sizeof(struct wlr_wl_shell_surface_popup_state));
|
||||
if (popup_state == NULL) {
|
||||
free(transient_state);
|
||||
wl_client_post_no_memory(client);
|
||||
|
|
Loading…
Reference in New Issue