mirror of
https://github.com/swaywm/sway.git
synced 2026-04-24 06:46:22 -04:00
Merge branch 'master' of https://github.com/swaywm/sway
This commit is contained in:
commit
5845c6e3c0
45 changed files with 575 additions and 292 deletions
33
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
33
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
name: Bugs
|
||||
about: Crashes and other bugs
|
||||
labels: 'bug'
|
||||
|
||||
---
|
||||
|
||||
### Please read the following before submitting:
|
||||
- Please do NOT submit bug reports for questions. Ask questions on IRC at #sway on irc.freenode.net.
|
||||
- Proprietary graphics drivers, including nvidia, are not supported. Please use the open source equivalents, such as nouveau, if you would like to use Sway.
|
||||
- Problems with the Wayland version of Firefox are likely to be Firefox bugs. Start by submitting your issue to the Firefox Bugzilla and come back here only after they confirm otherwise.
|
||||
|
||||
### Please fill out the following:
|
||||
- **Sway Version:**
|
||||
- `swaymsg -t get_version` or `sway -v`
|
||||
|
||||
- **Debug Log:**
|
||||
- Run `sway -d 2> ~/sway.log` from a TTY and upload it to a pastebin, such as gist.github.com.
|
||||
- This will record information about sway's activity. Please try to keep the reproduction as brief as possible and exit sway.
|
||||
|
||||
- **Configuration File:**
|
||||
- Please try to produce with the default configuration.
|
||||
- If you cannot reproduce with the default configuration, please try to find the minimal configuration to reproduce.
|
||||
- Upload the config to a pastebin such as gist.github.com.
|
||||
|
||||
- **Stack Trace:**
|
||||
- This is only needed if sway crashes.
|
||||
- If you use systemd, you should be able to open the coredump of the most recent crash with gdb with
|
||||
`coredumpctl gdb sway` and then `bt full` to obtain the stack trace.
|
||||
- If the lines mentioning sway or wlroots have `??` for the location, your binaries were built without debug symbols. Please compile both sway and wlroots from source and try to reproduce.
|
||||
|
||||
- **Description:**
|
||||
- The steps you took in plain English to reproduce the problem.
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Questions
|
||||
url: "http://webchat.freenode.net/?channels=sway&uio=d4"
|
||||
about: "Please ask questions on IRC in #sway on irc.freenode.net"
|
||||
13
.github/ISSUE_TEMPLATE/enhancement.md
vendored
Normal file
13
.github/ISSUE_TEMPLATE/enhancement.md
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
name: Enhancements
|
||||
about: New functionality
|
||||
labels: 'enhancement'
|
||||
|
||||
---
|
||||
|
||||
### Please read the following before submitting:
|
||||
- We are not accepting any new window management features unless they get implemented by i3. Please consider searching for or opening an i3 feature request.
|
||||
|
||||
### Please fill out the following:
|
||||
- **Description:**
|
||||
Please describe in plain English what the enhancement is and what the use case is.
|
||||
20
.github/ISSUE_TEMPLATE/i3_compat.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/i3_compat.md
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
name: i3 Compatibility
|
||||
about: Sway behaves differently from or lacks i3 functionality
|
||||
labels: 'i3-compat'
|
||||
|
||||
---
|
||||
|
||||
### Please read the following before submitting:
|
||||
- The following either do not make sense for Wayland or we have decided against supporting:
|
||||
- `restart`
|
||||
- `resource`
|
||||
- saving and loading layouts
|
||||
- the i3 sync protocol
|
||||
|
||||
### Please fill out the following:
|
||||
- **i3 PR:**
|
||||
- If this is new i3 functionality, please add a link to the i3 pull request.
|
||||
|
||||
- **Description:**
|
||||
- Please describe in plain English how Sway and i3's behaviors differ or what functionality Sway is lacking.
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
If you want to ask a question, please check out the wiki. If you don't find an answer there, ask on IRC (#sway on irc.freenode.net). The issue tracker may not be used for questions.
|
||||
|
||||
If you are using the Nvidia proprietary driver for any reason, you have two choices:
|
||||
|
||||
1. Uninstall it and use nouveau instead
|
||||
2. Use X11+i3 and close your browser tab
|
||||
|
||||
If `lsmod | grep nvidia | wc -l` shows anything other than zero, your bug report is not welcome here.
|
||||
|
||||
Additionally, problems with Firefox are almost certainly Firefox bugs, not sway bugs. Start by submitting your issue to the Firefox Bugzilla and come back here only after they confirm otherwise.
|
||||
|
||||
Otherwise, please include the following four components in your bug report: sway version, debug log, configuration (if applicable), and an explanation of steps taken to reproduce the issue. If sway crashes, also include a stack trace.
|
||||
|
||||
Obtain your version like so:
|
||||
|
||||
swaymsg -t get_version
|
||||
|
||||
If this doesn't work, use:
|
||||
|
||||
sway -v
|
||||
|
||||
* Sway Version:
|
||||
|
||||
Obtain a debug log by running the following command from a TTY:
|
||||
|
||||
sway -d 2> ~/sway.log
|
||||
|
||||
This will record information about sway's activity when it's running. Briefly reproduce your problem and exit sway. When preparing a debug log, brevity is important - start up sway, do the minimum work necessary to reproduce the error, then close sway.
|
||||
|
||||
Upload the debug log to a pastebin service such as [gist.github.com](https://gist.github.com), and link to it below.
|
||||
|
||||
* Debug Log:
|
||||
|
||||
You should try to reproduce the issue with the default configuration. If you cannot, please reproduce with a minimal configuration, upload the config to a pastebin service, and link to it below.
|
||||
|
||||
* Configuration File:
|
||||
|
||||
Finally, explain the steps you took in plain English to reproduce the problem below.
|
||||
|
||||
* Stack Trace, if sway crashes:
|
||||
|
||||
If you use systemd, you should be able to open the coredump of the most recent crash with GDB like so:
|
||||
|
||||
coredumpctl gdb sway
|
||||
|
||||
And then type `bt full` to obtain the stack trace.
|
||||
|
||||
If the lines mentioning sway/wlroots have "??" for the location, your binaries were built without debug symbols, and the stack trace is unlikely to be useful. You can find instructions to compile sway from source [here](https://github.com/swaywm/sway/wiki/Development-Setup#compiling-as-a-subproject). Note that debug symbols are included in Meson builds by default.
|
||||
|
|
@ -28,6 +28,8 @@ channel or shoot an email to sir@cmpwn.com for advice.
|
|||
|
||||
### Compiling from Source
|
||||
|
||||
Check out [this wiki page](https://github.com/swaywm/sway/wiki/Development-Setup) if you want to build the HEAD of sway and wlroots for testing or development.
|
||||
|
||||
Install dependencies:
|
||||
|
||||
* meson \*
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ bool ipc_set_recv_timeout(int socketfd, struct timeval tv) {
|
|||
|
||||
struct ipc_response *ipc_recv_response(int socketfd) {
|
||||
char data[IPC_HEADER_SIZE];
|
||||
uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic));
|
||||
|
||||
size_t total = 0;
|
||||
while (total < IPC_HEADER_SIZE) {
|
||||
|
|
@ -95,15 +94,15 @@ struct ipc_response *ipc_recv_response(int socketfd) {
|
|||
goto error_1;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
memcpy(&response->size, &data32[0], sizeof(data32[0]));
|
||||
memcpy(&response->type, &data32[1], sizeof(data32[1]));
|
||||
memcpy(&response->size, data + sizeof(ipc_magic), sizeof(uint32_t));
|
||||
memcpy(&response->type, data + sizeof(ipc_magic) + sizeof(uint32_t), sizeof(uint32_t));
|
||||
|
||||
char *payload = malloc(response->size + 1);
|
||||
if (!payload) {
|
||||
goto error_2;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
while (total < response->size) {
|
||||
ssize_t received = recv(socketfd, payload + total, response->size - total, 0);
|
||||
if (received < 0) {
|
||||
|
|
@ -129,10 +128,9 @@ void free_ipc_response(struct ipc_response *response) {
|
|||
|
||||
char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len) {
|
||||
char data[IPC_HEADER_SIZE];
|
||||
uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic));
|
||||
memcpy(data, ipc_magic, sizeof(ipc_magic));
|
||||
memcpy(&data32[0], len, sizeof(*len));
|
||||
memcpy(&data32[1], &type, sizeof(type));
|
||||
memcpy(data + sizeof(ipc_magic), len, sizeof(*len));
|
||||
memcpy(data + sizeof(ipc_magic) + sizeof(*len), &type, sizeof(type));
|
||||
|
||||
if (write(socketfd, data, IPC_HEADER_SIZE) == -1) {
|
||||
sway_abort("Unable to send IPC header");
|
||||
|
|
|
|||
|
|
@ -117,9 +117,15 @@ void loop_add_fd(struct loop *loop, int fd, short mask,
|
|||
struct pollfd pfd = {fd, mask, 0};
|
||||
|
||||
if (loop->fd_length == loop->fd_capacity) {
|
||||
loop->fd_capacity += 10;
|
||||
loop->fds = realloc(loop->fds,
|
||||
sizeof(struct pollfd) * loop->fd_capacity);
|
||||
int capacity = loop->fd_capacity + 10;
|
||||
struct pollfd *tmp = realloc(loop->fds,
|
||||
sizeof(struct pollfd) * capacity);
|
||||
if (!tmp) {
|
||||
sway_log(SWAY_ERROR, "Unable to allocate memory for pollfd");
|
||||
return;
|
||||
}
|
||||
loop->fds = tmp;
|
||||
loop->fd_capacity = capacity;
|
||||
}
|
||||
|
||||
loop->fds[loop->fd_length++] = pfd;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,40 @@ float parse_float(const char *value) {
|
|||
return flt;
|
||||
}
|
||||
|
||||
enum movement_unit parse_movement_unit(const char *unit) {
|
||||
if (strcasecmp(unit, "px") == 0) {
|
||||
return MOVEMENT_UNIT_PX;
|
||||
}
|
||||
if (strcasecmp(unit, "ppt") == 0) {
|
||||
return MOVEMENT_UNIT_PPT;
|
||||
}
|
||||
if (strcasecmp(unit, "default") == 0) {
|
||||
return MOVEMENT_UNIT_DEFAULT;
|
||||
}
|
||||
return MOVEMENT_UNIT_INVALID;
|
||||
}
|
||||
|
||||
int parse_movement_amount(int argc, char **argv,
|
||||
struct movement_amount *amount) {
|
||||
char *err;
|
||||
amount->amount = (int)strtol(argv[0], &err, 10);
|
||||
if (*err) {
|
||||
// e.g. 10px
|
||||
amount->unit = parse_movement_unit(err);
|
||||
return 1;
|
||||
}
|
||||
if (argc == 1) {
|
||||
amount->unit = MOVEMENT_UNIT_DEFAULT;
|
||||
return 1;
|
||||
}
|
||||
// Try the second argument
|
||||
amount->unit = parse_movement_unit(argv[1]);
|
||||
if (amount->unit == MOVEMENT_UNIT_INVALID) {
|
||||
amount->unit = MOVEMENT_UNIT_DEFAULT;
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
const char *sway_wl_output_subpixel_to_string(enum wl_output_subpixel subpixel) {
|
||||
switch (subpixel) {
|
||||
|
|
|
|||
43
config.in
43
config.in
|
|
@ -37,8 +37,7 @@ output * bg @datadir@/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill
|
|||
#
|
||||
# exec swayidle -w \
|
||||
# timeout 300 'swaylock -f -c 000000' \
|
||||
# timeout 600 'swaymsg "output * dpms off"' \
|
||||
# resume 'swaymsg "output * dpms on"' \
|
||||
# timeout 600 'swaymsg "output * dpms off"' resume 'swaymsg "output * dpms on"' \
|
||||
# before-sleep 'swaylock -f -c 000000'
|
||||
#
|
||||
# This will lock your screen after 300 seconds of inactivity, then turn off
|
||||
|
|
@ -112,27 +111,27 @@ output * bg @datadir@/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill
|
|||
# Workspaces:
|
||||
#
|
||||
# Switch to workspace
|
||||
bindsym $mod+1 workspace 1
|
||||
bindsym $mod+2 workspace 2
|
||||
bindsym $mod+3 workspace 3
|
||||
bindsym $mod+4 workspace 4
|
||||
bindsym $mod+5 workspace 5
|
||||
bindsym $mod+6 workspace 6
|
||||
bindsym $mod+7 workspace 7
|
||||
bindsym $mod+8 workspace 8
|
||||
bindsym $mod+9 workspace 9
|
||||
bindsym $mod+0 workspace 10
|
||||
bindsym $mod+1 workspace number 1
|
||||
bindsym $mod+2 workspace number 2
|
||||
bindsym $mod+3 workspace number 3
|
||||
bindsym $mod+4 workspace number 4
|
||||
bindsym $mod+5 workspace number 5
|
||||
bindsym $mod+6 workspace number 6
|
||||
bindsym $mod+7 workspace number 7
|
||||
bindsym $mod+8 workspace number 8
|
||||
bindsym $mod+9 workspace number 9
|
||||
bindsym $mod+0 workspace number 10
|
||||
# Move focused container to workspace
|
||||
bindsym $mod+Shift+1 move container to workspace 1
|
||||
bindsym $mod+Shift+2 move container to workspace 2
|
||||
bindsym $mod+Shift+3 move container to workspace 3
|
||||
bindsym $mod+Shift+4 move container to workspace 4
|
||||
bindsym $mod+Shift+5 move container to workspace 5
|
||||
bindsym $mod+Shift+6 move container to workspace 6
|
||||
bindsym $mod+Shift+7 move container to workspace 7
|
||||
bindsym $mod+Shift+8 move container to workspace 8
|
||||
bindsym $mod+Shift+9 move container to workspace 9
|
||||
bindsym $mod+Shift+0 move container to workspace 10
|
||||
bindsym $mod+Shift+1 move container to workspace number 1
|
||||
bindsym $mod+Shift+2 move container to workspace number 2
|
||||
bindsym $mod+Shift+3 move container to workspace number 3
|
||||
bindsym $mod+Shift+4 move container to workspace number 4
|
||||
bindsym $mod+Shift+5 move container to workspace number 5
|
||||
bindsym $mod+Shift+6 move container to workspace number 6
|
||||
bindsym $mod+Shift+7 move container to workspace number 7
|
||||
bindsym $mod+Shift+8 move container to workspace number 8
|
||||
bindsym $mod+Shift+9 move container to workspace number 9
|
||||
bindsym $mod+Shift+0 move container to workspace number 10
|
||||
# Note: workspaces can have any name you want, not just numbers.
|
||||
# We just use 1-10 as the default.
|
||||
#
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
#!/bin/sh -eu
|
||||
old_version="$1"
|
||||
new_version="$2"
|
||||
|
||||
if [ "$new_version" != "${new_version#v}" ]
|
||||
then
|
||||
echo "Error: The new version shouldn't be prefixed with a \"v\"." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sed -i meson.build -e "s/^ version: .*#release_version/ version: '$new_version', #release_version/g"
|
||||
|
||||
printf "Minimum wlroots version? "
|
||||
|
|
|
|||
|
|
@ -111,6 +111,10 @@ if [ "$ACTION" = "check" ] ; then
|
|||
exit
|
||||
elif [ "$SUBJECT" = "area" ] ; then
|
||||
GEOM=$(slurp -d)
|
||||
# Check if user exited slurp without selecting the area
|
||||
if [ -z "$GEOM" ]; then
|
||||
exit
|
||||
fi
|
||||
WHAT="Area"
|
||||
elif [ "$SUBJECT" = "active" ] ; then
|
||||
FOCUSED=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]?, .floating_nodes[]?) | select(.focused)')
|
||||
|
|
@ -126,6 +130,10 @@ elif [ "$SUBJECT" = "output" ] ; then
|
|||
WHAT="$OUTPUT"
|
||||
elif [ "$SUBJECT" = "window" ] ; then
|
||||
GEOM=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp)
|
||||
# Check if user exited slurp without selecting the area
|
||||
if [ -z "$GEOM" ]; then
|
||||
exit
|
||||
fi
|
||||
WHAT="Window"
|
||||
else
|
||||
die "Unknown subject to take a screen shot from" "$SUBJECT"
|
||||
|
|
|
|||
|
|
@ -500,6 +500,7 @@ struct sway_config {
|
|||
struct side_gaps gaps_outer;
|
||||
|
||||
list_t *config_chain;
|
||||
bool user_config_path;
|
||||
const char *current_config_path;
|
||||
const char *current_config;
|
||||
int current_config_line_number;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ struct sway_output {
|
|||
// last applied mode when the output is DPMS'ed
|
||||
struct wlr_output_mode *current_mode;
|
||||
|
||||
bool enabled, configured;
|
||||
bool enabling, enabled;
|
||||
list_t *workspaces;
|
||||
|
||||
struct sway_output_state current;
|
||||
|
|
@ -98,7 +98,7 @@ struct sway_output *all_output_by_name_or_id(const char *name_or_id);
|
|||
|
||||
void output_sort_workspaces(struct sway_output *output);
|
||||
|
||||
void output_configure(struct sway_output *output);
|
||||
void output_enable(struct sway_output *output);
|
||||
|
||||
void output_disable(struct sway_output *output);
|
||||
|
||||
|
|
|
|||
|
|
@ -219,6 +219,8 @@ void container_floating_resize_and_center(struct sway_container *con);
|
|||
|
||||
void container_floating_set_default_size(struct sway_container *con);
|
||||
|
||||
void container_set_resizing(struct sway_container *con, bool resizing);
|
||||
|
||||
void container_set_floating(struct sway_container *container, bool enable);
|
||||
|
||||
void container_set_geometry_from_content(struct sway_container *con);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ struct sway_view_impl {
|
|||
void (*set_activated)(struct sway_view *view, bool activated);
|
||||
void (*set_tiled)(struct sway_view *view, bool tiled);
|
||||
void (*set_fullscreen)(struct sway_view *view, bool fullscreen);
|
||||
void (*set_resizing)(struct sway_view *view, bool resizing);
|
||||
bool (*wants_floating)(struct sway_view *view);
|
||||
void (*for_each_surface)(struct sway_view *view,
|
||||
wlr_surface_iterator_func_t iterator, void *user_data);
|
||||
|
|
@ -146,6 +147,7 @@ struct sway_xwayland_view {
|
|||
struct wl_listener request_move;
|
||||
struct wl_listener request_resize;
|
||||
struct wl_listener request_maximize;
|
||||
struct wl_listener request_minimize;
|
||||
struct wl_listener request_configure;
|
||||
struct wl_listener request_fullscreen;
|
||||
struct wl_listener request_activate;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,30 @@
|
|||
#include <stdbool.h>
|
||||
#include <wayland-server-protocol.h>
|
||||
|
||||
enum movement_unit {
|
||||
MOVEMENT_UNIT_PX,
|
||||
MOVEMENT_UNIT_PPT,
|
||||
MOVEMENT_UNIT_DEFAULT,
|
||||
MOVEMENT_UNIT_INVALID,
|
||||
};
|
||||
|
||||
struct movement_amount {
|
||||
int amount;
|
||||
enum movement_unit unit;
|
||||
};
|
||||
|
||||
/*
|
||||
* Parse units such as "px" or "ppt"
|
||||
*/
|
||||
enum movement_unit parse_movement_unit(const char *unit);
|
||||
|
||||
/*
|
||||
* Parse arguments such as "10", "10px" or "10 px".
|
||||
* Returns the number of arguments consumed.
|
||||
*/
|
||||
int parse_movement_amount(int argc, char **argv,
|
||||
struct movement_amount *amount);
|
||||
|
||||
/**
|
||||
* Get the current time, in milliseconds.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
project(
|
||||
'sway',
|
||||
'c',
|
||||
version: 'v1.5-rc2', #release_version
|
||||
version: '1.5', #release_version
|
||||
license: 'MIT',
|
||||
meson_version: '>=0.53.0',
|
||||
default_options: [
|
||||
|
|
@ -60,7 +60,7 @@ math = cc.find_library('m')
|
|||
rt = cc.find_library('rt')
|
||||
|
||||
# Try first to find wlroots as a subproject, then as a system dependency
|
||||
wlroots_version = ['>=0.10.0', '<0.11.0']
|
||||
wlroots_version = ['>=0.11.0', '<0.12.0']
|
||||
wlroots_proj = subproject(
|
||||
'wlroots',
|
||||
default_options: ['examples=false'],
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@ static struct cmd_handler handlers[] = {
|
|||
{ "fullscreen", cmd_fullscreen },
|
||||
{ "gaps", cmd_gaps },
|
||||
{ "hide_edge_borders", cmd_hide_edge_borders },
|
||||
{ "include", cmd_include },
|
||||
{ "input", cmd_input },
|
||||
{ "mode", cmd_mode },
|
||||
{ "mouse_warping", cmd_mouse_warping },
|
||||
|
|
@ -101,6 +100,7 @@ static struct cmd_handler handlers[] = {
|
|||
/* Config-time only commands. Keep alphabetized */
|
||||
static struct cmd_handler config_handlers[] = {
|
||||
{ "default_orientation", cmd_default_orientation },
|
||||
{ "include", cmd_include },
|
||||
{ "swaybg_command", cmd_swaybg_command },
|
||||
{ "swaynag_command", cmd_swaynag_command },
|
||||
{ "workspace_layout", cmd_workspace_layout },
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ static char *hex_to_rgba_hex(const char *hex) {
|
|||
return NULL;
|
||||
}
|
||||
char *rgba = malloc(10);
|
||||
if (!rgba) {
|
||||
return NULL;
|
||||
}
|
||||
snprintf(rgba, 10, "#%08x", color);
|
||||
return rgba;
|
||||
}
|
||||
|
|
@ -36,7 +39,7 @@ static struct cmd_results *parse_single_color(char **color,
|
|||
}
|
||||
|
||||
char *rgba = hex_to_rgba_hex(argv[0]);
|
||||
if (!*rgba) {
|
||||
if (!rgba) {
|
||||
return cmd_results_new(CMD_INVALID, "Invalid color: %s", argv[0]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -715,7 +715,7 @@ bool translate_binding(struct sway_binding *binding) {
|
|||
struct keycode_matches matches = get_keycode_for_keysym(*keysym);
|
||||
|
||||
if (matches.count != 1) {
|
||||
sway_log(SWAY_INFO, "Unable to convert keysym %d into"
|
||||
sway_log(SWAY_INFO, "Unable to convert keysym %" PRIu32 " into"
|
||||
" a single keycode (found %d matches)",
|
||||
*keysym, matches.count);
|
||||
goto error;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
|
@ -753,6 +754,38 @@ static struct cmd_results *cmd_move_in_direction(
|
|||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
||||
static struct cmd_results *cmd_move_to_position_pointer(
|
||||
struct sway_container *container) {
|
||||
struct sway_seat *seat = config->handler_context.seat;
|
||||
if (!seat->cursor) {
|
||||
return cmd_results_new(CMD_FAILURE, "No cursor device");
|
||||
}
|
||||
struct wlr_cursor *cursor = seat->cursor->cursor;
|
||||
/* Determine where to put the window. */
|
||||
double lx = cursor->x - container->width / 2;
|
||||
double ly = cursor->y - container->height / 2;
|
||||
|
||||
/* Correct target coordinates to be in bounds (on screen). */
|
||||
struct wlr_output *output = wlr_output_layout_output_at(
|
||||
root->output_layout, cursor->x, cursor->y);
|
||||
if (output) {
|
||||
struct wlr_box *box =
|
||||
wlr_output_layout_get_box(root->output_layout, output);
|
||||
lx = fmax(lx, box->x);
|
||||
ly = fmax(ly, box->y);
|
||||
if (lx + container->width > box->x + box->width) {
|
||||
lx = box->x + box->width - container->width;
|
||||
}
|
||||
if (ly + container->height > box->y + box->height) {
|
||||
ly = box->y + box->height - container->height;
|
||||
}
|
||||
}
|
||||
|
||||
/* Actually move the container. */
|
||||
container_floating_move_to(container, lx, ly);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
||||
static const char expected_position_syntax[] =
|
||||
"Expected 'move [absolute] position <x> [px] <y> [px]' or "
|
||||
"'move [absolute] position center' or "
|
||||
|
|
@ -790,14 +823,7 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
|
|||
if (absolute) {
|
||||
return cmd_results_new(CMD_INVALID, expected_position_syntax);
|
||||
}
|
||||
struct sway_seat *seat = config->handler_context.seat;
|
||||
if (!seat->cursor) {
|
||||
return cmd_results_new(CMD_FAILURE, "No cursor device");
|
||||
}
|
||||
double lx = seat->cursor->cursor->x - container->width / 2;
|
||||
double ly = seat->cursor->cursor->y - container->height / 2;
|
||||
container_floating_move_to(container, lx, ly);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
return cmd_move_to_position_pointer(container);
|
||||
} else if (strcmp(argv[0], "center") == 0) {
|
||||
double lx, ly;
|
||||
if (absolute) {
|
||||
|
|
@ -820,37 +846,81 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
|
|||
return cmd_results_new(CMD_FAILURE, expected_position_syntax);
|
||||
}
|
||||
|
||||
double lx, ly;
|
||||
char *inv;
|
||||
lx = (double)strtol(argv[0], &inv, 10);
|
||||
if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
|
||||
return cmd_results_new(CMD_FAILURE, "Invalid position specified");
|
||||
}
|
||||
if (strcmp(argv[1], "px") == 0) {
|
||||
--argc;
|
||||
++argv;
|
||||
struct movement_amount lx = { .amount = 0, .unit = MOVEMENT_UNIT_INVALID };
|
||||
// X direction
|
||||
int num_consumed_args = parse_movement_amount(argc, argv, &lx);
|
||||
argc -= num_consumed_args;
|
||||
argv += num_consumed_args;
|
||||
if (lx.unit == MOVEMENT_UNIT_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, "Invalid x position specified");
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
return cmd_results_new(CMD_FAILURE, expected_position_syntax);
|
||||
struct movement_amount ly = { .amount = 0, .unit = MOVEMENT_UNIT_INVALID };
|
||||
// Y direction
|
||||
num_consumed_args = parse_movement_amount(argc, argv, &ly);
|
||||
argc -= num_consumed_args;
|
||||
argv += num_consumed_args;
|
||||
if (argc > 0) {
|
||||
return cmd_results_new(CMD_INVALID, expected_position_syntax);
|
||||
}
|
||||
if (ly.unit == MOVEMENT_UNIT_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, "Invalid y position specified");
|
||||
}
|
||||
|
||||
ly = (double)strtol(argv[1], &inv, 10);
|
||||
if ((*inv != '\0' && strcasecmp(inv, "px") != 0) ||
|
||||
(argc == 3 && strcmp(argv[2], "px") != 0)) {
|
||||
return cmd_results_new(CMD_FAILURE, "Invalid position specified");
|
||||
struct sway_workspace *ws = container->workspace;
|
||||
if (!ws) {
|
||||
struct sway_seat *seat = config->handler_context.seat;
|
||||
ws = seat_get_focused_workspace(seat);
|
||||
}
|
||||
|
||||
if (!absolute) {
|
||||
struct sway_workspace *ws = container->workspace;
|
||||
if (!ws) {
|
||||
struct sway_seat *seat = config->handler_context.seat;
|
||||
ws = seat_get_focused_workspace(seat);
|
||||
switch (lx.unit) {
|
||||
case MOVEMENT_UNIT_PPT:
|
||||
if (container_is_scratchpad_hidden(container)) {
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Cannot move a hidden scratchpad container by ppt");
|
||||
}
|
||||
lx += ws->x;
|
||||
ly += ws->y;
|
||||
if (absolute) {
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Cannot move to absolute positions by ppt");
|
||||
}
|
||||
// Convert to px
|
||||
lx.amount = ws->width * lx.amount / 100;
|
||||
lx.unit = MOVEMENT_UNIT_PX;
|
||||
// Falls through
|
||||
case MOVEMENT_UNIT_PX:
|
||||
case MOVEMENT_UNIT_DEFAULT:
|
||||
break;
|
||||
case MOVEMENT_UNIT_INVALID:
|
||||
sway_assert(false, "invalid x unit");
|
||||
break;
|
||||
}
|
||||
container_floating_move_to(container, lx, ly);
|
||||
|
||||
switch (ly.unit) {
|
||||
case MOVEMENT_UNIT_PPT:
|
||||
if (container_is_scratchpad_hidden(container)) {
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Cannot move a hidden scratchpad container by ppt");
|
||||
}
|
||||
if (absolute) {
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Cannot move to absolute positions by ppt");
|
||||
}
|
||||
// Convert to px
|
||||
ly.amount = ws->height * ly.amount / 100;
|
||||
ly.unit = MOVEMENT_UNIT_PX;
|
||||
// Falls through
|
||||
case MOVEMENT_UNIT_PX:
|
||||
case MOVEMENT_UNIT_DEFAULT:
|
||||
break;
|
||||
case MOVEMENT_UNIT_INVALID:
|
||||
sway_assert(false, "invalid y unit");
|
||||
break;
|
||||
}
|
||||
if (!absolute) {
|
||||
lx.amount += ws->x;
|
||||
ly.amount += ws->y;
|
||||
}
|
||||
container_floating_move_to(container, lx.amount, ly.amount);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,12 @@ static void do_reload(void *data) {
|
|||
list_add(bar_ids, strdup(bar->id));
|
||||
}
|
||||
|
||||
if (!load_main_config(config->current_config_path, true, false)) {
|
||||
const char *path = NULL;
|
||||
if (config->user_config_path) {
|
||||
path = config->current_config_path;
|
||||
}
|
||||
|
||||
if (!load_main_config(path, true, false)) {
|
||||
sway_log(SWAY_ERROR, "Error(s) reloading config");
|
||||
list_free_items_and_destroy(bar_ids);
|
||||
return;
|
||||
|
|
@ -55,7 +60,12 @@ struct cmd_results *cmd_reload(int argc, char **argv) {
|
|||
return error;
|
||||
}
|
||||
|
||||
if (!load_main_config(config->current_config_path, true, true)) {
|
||||
const char *path = NULL;
|
||||
if (config->user_config_path) {
|
||||
path = config->current_config_path;
|
||||
}
|
||||
|
||||
if (!load_main_config(path, true, true)) {
|
||||
return cmd_results_new(CMD_FAILURE, "Error(s) reloading config.");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,59 +11,11 @@
|
|||
#include "sway/tree/view.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
|
||||
#define AXIS_HORIZONTAL (WLR_EDGE_LEFT | WLR_EDGE_RIGHT)
|
||||
#define AXIS_VERTICAL (WLR_EDGE_TOP | WLR_EDGE_BOTTOM)
|
||||
|
||||
enum resize_unit {
|
||||
RESIZE_UNIT_PX,
|
||||
RESIZE_UNIT_PPT,
|
||||
RESIZE_UNIT_DEFAULT,
|
||||
RESIZE_UNIT_INVALID,
|
||||
};
|
||||
|
||||
struct resize_amount {
|
||||
int amount;
|
||||
enum resize_unit unit;
|
||||
};
|
||||
|
||||
static enum resize_unit parse_resize_unit(const char *unit) {
|
||||
if (strcasecmp(unit, "px") == 0) {
|
||||
return RESIZE_UNIT_PX;
|
||||
}
|
||||
if (strcasecmp(unit, "ppt") == 0) {
|
||||
return RESIZE_UNIT_PPT;
|
||||
}
|
||||
if (strcasecmp(unit, "default") == 0) {
|
||||
return RESIZE_UNIT_DEFAULT;
|
||||
}
|
||||
return RESIZE_UNIT_INVALID;
|
||||
}
|
||||
|
||||
// Parse arguments such as "10", "10px" or "10 px".
|
||||
// Returns the number of arguments consumed.
|
||||
static int parse_resize_amount(int argc, char **argv,
|
||||
struct resize_amount *amount) {
|
||||
char *err;
|
||||
amount->amount = (int)strtol(argv[0], &err, 10);
|
||||
if (*err) {
|
||||
// e.g. 10px
|
||||
amount->unit = parse_resize_unit(err);
|
||||
return 1;
|
||||
}
|
||||
if (argc == 1) {
|
||||
amount->unit = RESIZE_UNIT_DEFAULT;
|
||||
return 1;
|
||||
}
|
||||
// Try the second argument
|
||||
amount->unit = parse_resize_unit(argv[1]);
|
||||
if (amount->unit == RESIZE_UNIT_INVALID) {
|
||||
amount->unit = RESIZE_UNIT_DEFAULT;
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
static uint32_t parse_resize_axis(const char *axis) {
|
||||
if (strcasecmp(axis, "width") == 0 || strcasecmp(axis, "horizontal") == 0) {
|
||||
return AXIS_HORIZONTAL;
|
||||
|
|
@ -237,7 +189,7 @@ void container_resize_tiled(struct sway_container *con,
|
|||
* Implement `resize <grow|shrink>` for a floating container.
|
||||
*/
|
||||
static struct cmd_results *resize_adjust_floating(uint32_t axis,
|
||||
struct resize_amount *amount) {
|
||||
struct movement_amount *amount) {
|
||||
struct sway_container *con = config->handler_context.container;
|
||||
int grow_width = 0, grow_height = 0;
|
||||
|
||||
|
|
@ -294,13 +246,13 @@ static struct cmd_results *resize_adjust_floating(uint32_t axis,
|
|||
* Implement `resize <grow|shrink>` for a tiled container.
|
||||
*/
|
||||
static struct cmd_results *resize_adjust_tiled(uint32_t axis,
|
||||
struct resize_amount *amount) {
|
||||
struct movement_amount *amount) {
|
||||
struct sway_container *current = config->handler_context.container;
|
||||
|
||||
if (amount->unit == RESIZE_UNIT_DEFAULT) {
|
||||
amount->unit = RESIZE_UNIT_PPT;
|
||||
if (amount->unit == MOVEMENT_UNIT_DEFAULT) {
|
||||
amount->unit = MOVEMENT_UNIT_PPT;
|
||||
}
|
||||
if (amount->unit == RESIZE_UNIT_PPT) {
|
||||
if (amount->unit == MOVEMENT_UNIT_PPT) {
|
||||
float pct = amount->amount / 100.0f;
|
||||
|
||||
if (is_horizontal(axis)) {
|
||||
|
|
@ -324,10 +276,10 @@ static struct cmd_results *resize_adjust_tiled(uint32_t axis,
|
|||
* Implement `resize set` for a tiled container.
|
||||
*/
|
||||
static struct cmd_results *resize_set_tiled(struct sway_container *con,
|
||||
struct resize_amount *width, struct resize_amount *height) {
|
||||
struct movement_amount *width, struct movement_amount *height) {
|
||||
if (width->amount) {
|
||||
if (width->unit == RESIZE_UNIT_PPT ||
|
||||
width->unit == RESIZE_UNIT_DEFAULT) {
|
||||
if (width->unit == MOVEMENT_UNIT_PPT ||
|
||||
width->unit == MOVEMENT_UNIT_DEFAULT) {
|
||||
// Convert to px
|
||||
struct sway_container *parent = con->parent;
|
||||
while (parent && parent->layout != L_HORIZ) {
|
||||
|
|
@ -338,17 +290,17 @@ static struct cmd_results *resize_set_tiled(struct sway_container *con,
|
|||
} else {
|
||||
width->amount = con->workspace->width * width->amount / 100;
|
||||
}
|
||||
width->unit = RESIZE_UNIT_PX;
|
||||
width->unit = MOVEMENT_UNIT_PX;
|
||||
}
|
||||
if (width->unit == RESIZE_UNIT_PX) {
|
||||
if (width->unit == MOVEMENT_UNIT_PX) {
|
||||
container_resize_tiled(con, AXIS_HORIZONTAL,
|
||||
width->amount - con->width);
|
||||
}
|
||||
}
|
||||
|
||||
if (height->amount) {
|
||||
if (height->unit == RESIZE_UNIT_PPT ||
|
||||
height->unit == RESIZE_UNIT_DEFAULT) {
|
||||
if (height->unit == MOVEMENT_UNIT_PPT ||
|
||||
height->unit == MOVEMENT_UNIT_DEFAULT) {
|
||||
// Convert to px
|
||||
struct sway_container *parent = con->parent;
|
||||
while (parent && parent->layout != L_VERT) {
|
||||
|
|
@ -359,9 +311,9 @@ static struct cmd_results *resize_set_tiled(struct sway_container *con,
|
|||
} else {
|
||||
height->amount = con->workspace->height * height->amount / 100;
|
||||
}
|
||||
height->unit = RESIZE_UNIT_PX;
|
||||
height->unit = MOVEMENT_UNIT_PX;
|
||||
}
|
||||
if (height->unit == RESIZE_UNIT_PX) {
|
||||
if (height->unit == MOVEMENT_UNIT_PX) {
|
||||
container_resize_tiled(con, AXIS_VERTICAL,
|
||||
height->amount - con->height);
|
||||
}
|
||||
|
|
@ -374,30 +326,30 @@ static struct cmd_results *resize_set_tiled(struct sway_container *con,
|
|||
* Implement `resize set` for a floating container.
|
||||
*/
|
||||
static struct cmd_results *resize_set_floating(struct sway_container *con,
|
||||
struct resize_amount *width, struct resize_amount *height) {
|
||||
struct movement_amount *width, struct movement_amount *height) {
|
||||
int min_width, max_width, min_height, max_height, grow_width = 0, grow_height = 0;
|
||||
floating_calculate_constraints(&min_width, &max_width,
|
||||
&min_height, &max_height);
|
||||
|
||||
if (width->amount) {
|
||||
switch (width->unit) {
|
||||
case RESIZE_UNIT_PPT:
|
||||
case MOVEMENT_UNIT_PPT:
|
||||
if (container_is_scratchpad_hidden(con)) {
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Cannot resize a hidden scratchpad container by ppt");
|
||||
}
|
||||
// Convert to px
|
||||
width->amount = con->workspace->width * width->amount / 100;
|
||||
width->unit = RESIZE_UNIT_PX;
|
||||
width->unit = MOVEMENT_UNIT_PX;
|
||||
// Falls through
|
||||
case RESIZE_UNIT_PX:
|
||||
case RESIZE_UNIT_DEFAULT:
|
||||
case MOVEMENT_UNIT_PX:
|
||||
case MOVEMENT_UNIT_DEFAULT:
|
||||
width->amount = fmax(min_width, fmin(width->amount, max_width));
|
||||
grow_width = width->amount - con->width;
|
||||
con->x -= grow_width / 2;
|
||||
con->width = width->amount;
|
||||
break;
|
||||
case RESIZE_UNIT_INVALID:
|
||||
case MOVEMENT_UNIT_INVALID:
|
||||
sway_assert(false, "invalid width unit");
|
||||
break;
|
||||
}
|
||||
|
|
@ -405,23 +357,23 @@ static struct cmd_results *resize_set_floating(struct sway_container *con,
|
|||
|
||||
if (height->amount) {
|
||||
switch (height->unit) {
|
||||
case RESIZE_UNIT_PPT:
|
||||
case MOVEMENT_UNIT_PPT:
|
||||
if (container_is_scratchpad_hidden(con)) {
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Cannot resize a hidden scratchpad container by ppt");
|
||||
}
|
||||
// Convert to px
|
||||
height->amount = con->workspace->height * height->amount / 100;
|
||||
height->unit = RESIZE_UNIT_PX;
|
||||
height->unit = MOVEMENT_UNIT_PX;
|
||||
// Falls through
|
||||
case RESIZE_UNIT_PX:
|
||||
case RESIZE_UNIT_DEFAULT:
|
||||
case MOVEMENT_UNIT_PX:
|
||||
case MOVEMENT_UNIT_DEFAULT:
|
||||
height->amount = fmax(min_height, fmin(height->amount, max_height));
|
||||
grow_height = height->amount - con->height;
|
||||
con->y -= grow_height / 2;
|
||||
con->height = height->amount;
|
||||
break;
|
||||
case RESIZE_UNIT_INVALID:
|
||||
case MOVEMENT_UNIT_INVALID:
|
||||
sway_assert(false, "invalid height unit");
|
||||
break;
|
||||
}
|
||||
|
|
@ -454,30 +406,30 @@ static struct cmd_results *cmd_resize_set(int argc, char **argv) {
|
|||
"'resize set [width] <width> [px|ppt] [height] <height> [px|ppt]'";
|
||||
|
||||
// Width
|
||||
struct resize_amount width = {0};
|
||||
struct movement_amount width = {0};
|
||||
if (argc >= 2 && !strcmp(argv[0], "width") && strcmp(argv[1], "height")) {
|
||||
argc--; argv++;
|
||||
}
|
||||
if (strcmp(argv[0], "height")) {
|
||||
int num_consumed_args = parse_resize_amount(argc, argv, &width);
|
||||
int num_consumed_args = parse_movement_amount(argc, argv, &width);
|
||||
argc -= num_consumed_args;
|
||||
argv += num_consumed_args;
|
||||
if (width.unit == RESIZE_UNIT_INVALID) {
|
||||
if (width.unit == MOVEMENT_UNIT_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, usage);
|
||||
}
|
||||
}
|
||||
|
||||
// Height
|
||||
struct resize_amount height = {0};
|
||||
struct movement_amount height = {0};
|
||||
if (argc) {
|
||||
if (argc >= 2 && !strcmp(argv[0], "height")) {
|
||||
argc--; argv++;
|
||||
}
|
||||
int num_consumed_args = parse_resize_amount(argc, argv, &height);
|
||||
int num_consumed_args = parse_movement_amount(argc, argv, &height);
|
||||
if (argc > num_consumed_args) {
|
||||
return cmd_results_new(CMD_INVALID, usage);
|
||||
}
|
||||
if (width.unit == RESIZE_UNIT_INVALID) {
|
||||
if (width.unit == MOVEMENT_UNIT_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, usage);
|
||||
}
|
||||
}
|
||||
|
|
@ -515,17 +467,17 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
|
|||
--argc; ++argv;
|
||||
|
||||
// First amount
|
||||
struct resize_amount first_amount;
|
||||
struct movement_amount first_amount;
|
||||
if (argc) {
|
||||
int num_consumed_args = parse_resize_amount(argc, argv, &first_amount);
|
||||
int num_consumed_args = parse_movement_amount(argc, argv, &first_amount);
|
||||
argc -= num_consumed_args;
|
||||
argv += num_consumed_args;
|
||||
if (first_amount.unit == RESIZE_UNIT_INVALID) {
|
||||
if (first_amount.unit == MOVEMENT_UNIT_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, usage);
|
||||
}
|
||||
} else {
|
||||
first_amount.amount = 10;
|
||||
first_amount.unit = RESIZE_UNIT_DEFAULT;
|
||||
first_amount.unit = MOVEMENT_UNIT_DEFAULT;
|
||||
}
|
||||
|
||||
// "or"
|
||||
|
|
@ -537,18 +489,18 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
|
|||
}
|
||||
|
||||
// Second amount
|
||||
struct resize_amount second_amount;
|
||||
struct movement_amount second_amount;
|
||||
if (argc) {
|
||||
int num_consumed_args = parse_resize_amount(argc, argv, &second_amount);
|
||||
int num_consumed_args = parse_movement_amount(argc, argv, &second_amount);
|
||||
if (argc > num_consumed_args) {
|
||||
return cmd_results_new(CMD_INVALID, usage);
|
||||
}
|
||||
if (second_amount.unit == RESIZE_UNIT_INVALID) {
|
||||
if (second_amount.unit == MOVEMENT_UNIT_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, usage);
|
||||
}
|
||||
} else {
|
||||
second_amount.amount = 0;
|
||||
second_amount.unit = RESIZE_UNIT_INVALID;
|
||||
second_amount.unit = MOVEMENT_UNIT_INVALID;
|
||||
}
|
||||
|
||||
first_amount.amount *= multiplier;
|
||||
|
|
@ -558,13 +510,13 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
|
|||
if (container_is_floating(con)) {
|
||||
// Floating containers can only resize in px. Choose an amount which
|
||||
// uses px, with fallback to an amount that specified no unit.
|
||||
if (first_amount.unit == RESIZE_UNIT_PX) {
|
||||
if (first_amount.unit == MOVEMENT_UNIT_PX) {
|
||||
return resize_adjust_floating(axis, &first_amount);
|
||||
} else if (second_amount.unit == RESIZE_UNIT_PX) {
|
||||
} else if (second_amount.unit == MOVEMENT_UNIT_PX) {
|
||||
return resize_adjust_floating(axis, &second_amount);
|
||||
} else if (first_amount.unit == RESIZE_UNIT_DEFAULT) {
|
||||
} else if (first_amount.unit == MOVEMENT_UNIT_DEFAULT) {
|
||||
return resize_adjust_floating(axis, &first_amount);
|
||||
} else if (second_amount.unit == RESIZE_UNIT_DEFAULT) {
|
||||
} else if (second_amount.unit == MOVEMENT_UNIT_DEFAULT) {
|
||||
return resize_adjust_floating(axis, &second_amount);
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
|
|
@ -573,13 +525,13 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
|
|||
}
|
||||
|
||||
// For tiling, prefer ppt -> default -> px
|
||||
if (first_amount.unit == RESIZE_UNIT_PPT) {
|
||||
if (first_amount.unit == MOVEMENT_UNIT_PPT) {
|
||||
return resize_adjust_tiled(axis, &first_amount);
|
||||
} else if (second_amount.unit == RESIZE_UNIT_PPT) {
|
||||
} else if (second_amount.unit == MOVEMENT_UNIT_PPT) {
|
||||
return resize_adjust_tiled(axis, &second_amount);
|
||||
} else if (first_amount.unit == RESIZE_UNIT_DEFAULT) {
|
||||
} else if (first_amount.unit == MOVEMENT_UNIT_DEFAULT) {
|
||||
return resize_adjust_tiled(axis, &first_amount);
|
||||
} else if (second_amount.unit == RESIZE_UNIT_DEFAULT) {
|
||||
} else if (second_amount.unit == MOVEMENT_UNIT_DEFAULT) {
|
||||
return resize_adjust_tiled(axis, &second_amount);
|
||||
} else {
|
||||
return resize_adjust_tiled(axis, &first_amount);
|
||||
|
|
|
|||
|
|
@ -447,6 +447,7 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
|
|||
}
|
||||
}
|
||||
|
||||
config->user_config_path = file ? true : false;
|
||||
config->current_config_path = path;
|
||||
list_add(config->config_chain, real_path);
|
||||
|
||||
|
|
|
|||
|
|
@ -397,17 +397,8 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
|||
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
|
||||
bool was_enabled = output->enabled;
|
||||
if (oc && !oc->enabled) {
|
||||
// Output is configured to be disabled
|
||||
sway_log(SWAY_DEBUG, "Disabling output %s", oc->name);
|
||||
if (output->enabled) {
|
||||
output_disable(output);
|
||||
wlr_output_layout_remove(root->output_layout, wlr_output);
|
||||
}
|
||||
} else {
|
||||
output->enabled = true;
|
||||
}
|
||||
// Flag to prevent the output mode event handler from calling us
|
||||
output->enabling = (!oc || oc->enabled);
|
||||
|
||||
queue_output_config(oc, output);
|
||||
|
||||
|
|
@ -421,11 +412,18 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
|||
// Leave the output disabled for now and try again when the output gets
|
||||
// the mode we asked for.
|
||||
sway_log(SWAY_ERROR, "Failed to commit output %s", wlr_output->name);
|
||||
output->enabled = was_enabled;
|
||||
output->enabling = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
output->enabling = false;
|
||||
|
||||
if (oc && !oc->enabled) {
|
||||
sway_log(SWAY_DEBUG, "Disabling output %s", oc->name);
|
||||
if (output->enabled) {
|
||||
output_disable(output);
|
||||
wlr_output_layout_remove(root->output_layout, wlr_output);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -468,8 +466,8 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
|||
output->width = output_box->width;
|
||||
output->height = output_box->height;
|
||||
|
||||
if (!output->configured) {
|
||||
output_configure(output);
|
||||
if (!output->enabled) {
|
||||
output_enable(output);
|
||||
}
|
||||
|
||||
if (oc && oc->max_render_time >= 0) {
|
||||
|
|
|
|||
|
|
@ -510,11 +510,11 @@ struct sway_layer_surface *layer_from_wlr_layer_surface_v1(
|
|||
|
||||
void handle_layer_shell_surface(struct wl_listener *listener, void *data) {
|
||||
struct wlr_layer_surface_v1 *layer_surface = data;
|
||||
sway_log(SWAY_DEBUG, "new layer surface: namespace %s layer %d anchor %d "
|
||||
"size %dx%d margin %d,%d,%d,%d",
|
||||
sway_log(SWAY_DEBUG, "new layer surface: namespace %s layer %d anchor %" PRIu32
|
||||
" size %" PRIu32 "x%" PRIu32 " margin %" PRIu32 ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 ",",
|
||||
layer_surface->namespace,
|
||||
layer_surface->client_pending.layer,
|
||||
layer_surface->client_pending.layer,
|
||||
layer_surface->client_pending.anchor,
|
||||
layer_surface->client_pending.desired_width,
|
||||
layer_surface->client_pending.desired_height,
|
||||
layer_surface->client_pending.margin.top,
|
||||
|
|
|
|||
|
|
@ -844,7 +844,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
|||
|
||||
static void handle_mode(struct wl_listener *listener, void *data) {
|
||||
struct sway_output *output = wl_container_of(listener, output, mode);
|
||||
if (!output->configured && !output->enabled) {
|
||||
if (!output->enabled && !output->enabling) {
|
||||
struct output_config *oc = find_output_config(output);
|
||||
if (output->wlr_output->current_mode != NULL &&
|
||||
(!oc || oc->enabled)) {
|
||||
|
|
@ -857,7 +857,7 @@ static void handle_mode(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
return;
|
||||
}
|
||||
if (!output->enabled || !output->configured) {
|
||||
if (!output->enabled) {
|
||||
return;
|
||||
}
|
||||
arrange_layers(output);
|
||||
|
|
@ -869,7 +869,7 @@ static void handle_mode(struct wl_listener *listener, void *data) {
|
|||
|
||||
static void handle_transform(struct wl_listener *listener, void *data) {
|
||||
struct sway_output *output = wl_container_of(listener, output, transform);
|
||||
if (!output->enabled || !output->configured) {
|
||||
if (!output->enabled) {
|
||||
return;
|
||||
}
|
||||
arrange_layers(output);
|
||||
|
|
@ -886,7 +886,7 @@ static void update_textures(struct sway_container *con, void *data) {
|
|||
|
||||
static void handle_scale(struct wl_listener *listener, void *data) {
|
||||
struct sway_output *output = wl_container_of(listener, output, scale);
|
||||
if (!output->enabled || !output->configured) {
|
||||
if (!output->enabled) {
|
||||
return;
|
||||
}
|
||||
arrange_layers(output);
|
||||
|
|
@ -996,7 +996,8 @@ static void output_manager_apply(struct sway_server *server,
|
|||
} else {
|
||||
oc->width = config_head->state.custom_mode.width;
|
||||
oc->height = config_head->state.custom_mode.height;
|
||||
oc->refresh_rate = config_head->state.custom_mode.refresh;
|
||||
oc->refresh_rate =
|
||||
config_head->state.custom_mode.refresh / 1000.f;
|
||||
}
|
||||
oc->x = config_head->state.x;
|
||||
oc->y = config_head->state.y;
|
||||
|
|
|
|||
|
|
@ -185,6 +185,14 @@ static void set_fullscreen(struct sway_view *view, bool fullscreen) {
|
|||
wlr_xdg_toplevel_set_fullscreen(surface, fullscreen);
|
||||
}
|
||||
|
||||
static void set_resizing(struct sway_view *view, bool resizing) {
|
||||
if (xdg_shell_view_from_view(view) == NULL) {
|
||||
return;
|
||||
}
|
||||
struct wlr_xdg_surface *surface = view->wlr_xdg_surface;
|
||||
wlr_xdg_toplevel_set_resizing(surface, resizing);
|
||||
}
|
||||
|
||||
static bool wants_floating(struct sway_view *view) {
|
||||
struct wlr_xdg_toplevel *toplevel = view->wlr_xdg_surface->toplevel;
|
||||
struct wlr_xdg_toplevel_state *state = &toplevel->current;
|
||||
|
|
@ -260,6 +268,7 @@ static const struct sway_view_impl view_impl = {
|
|||
.set_activated = set_activated,
|
||||
.set_tiled = set_tiled,
|
||||
.set_fullscreen = set_fullscreen,
|
||||
.set_resizing = set_resizing,
|
||||
.wants_floating = wants_floating,
|
||||
.for_each_surface = for_each_surface,
|
||||
.for_each_popup = for_each_popup,
|
||||
|
|
@ -360,6 +369,11 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
|
|||
transaction_commit_dirty();
|
||||
}
|
||||
|
||||
static void handle_request_maximize(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xdg_surface *surface = data;
|
||||
wlr_xdg_surface_schedule_configure(surface);
|
||||
}
|
||||
|
||||
static void handle_request_move(struct wl_listener *listener, void *data) {
|
||||
struct sway_xdg_shell_view *xdg_shell_view =
|
||||
wl_container_of(listener, xdg_shell_view, request_move);
|
||||
|
|
@ -402,6 +416,7 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
|
|||
wl_list_remove(&xdg_shell_view->commit.link);
|
||||
wl_list_remove(&xdg_shell_view->new_popup.link);
|
||||
wl_list_remove(&xdg_shell_view->request_fullscreen.link);
|
||||
wl_list_remove(&xdg_shell_view->request_maximize.link);
|
||||
wl_list_remove(&xdg_shell_view->request_move.link);
|
||||
wl_list_remove(&xdg_shell_view->request_resize.link);
|
||||
wl_list_remove(&xdg_shell_view->set_title.link);
|
||||
|
|
@ -450,6 +465,10 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
|||
wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen,
|
||||
&xdg_shell_view->request_fullscreen);
|
||||
|
||||
xdg_shell_view->request_maximize.notify = handle_request_maximize;
|
||||
wl_signal_add(&xdg_surface->toplevel->events.request_maximize,
|
||||
&xdg_shell_view->request_maximize);
|
||||
|
||||
xdg_shell_view->request_move.notify = handle_request_move;
|
||||
wl_signal_add(&xdg_surface->toplevel->events.request_move,
|
||||
&xdg_shell_view->request_move);
|
||||
|
|
|
|||
|
|
@ -222,6 +222,11 @@ static void set_activated(struct sway_view *view, bool activated) {
|
|||
return;
|
||||
}
|
||||
struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface;
|
||||
|
||||
if (activated && surface->minimized) {
|
||||
wlr_xwayland_surface_set_minimized(surface, false);
|
||||
}
|
||||
|
||||
wlr_xwayland_surface_activate(surface, activated);
|
||||
}
|
||||
|
||||
|
|
@ -406,6 +411,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
|||
wl_list_remove(&xwayland_view->destroy.link);
|
||||
wl_list_remove(&xwayland_view->request_configure.link);
|
||||
wl_list_remove(&xwayland_view->request_fullscreen.link);
|
||||
wl_list_remove(&xwayland_view->request_minimize.link);
|
||||
wl_list_remove(&xwayland_view->request_move.link);
|
||||
wl_list_remove(&xwayland_view->request_resize.link);
|
||||
wl_list_remove(&xwayland_view->request_activate.link);
|
||||
|
|
@ -508,6 +514,21 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
|
|||
transaction_commit_dirty();
|
||||
}
|
||||
|
||||
static void handle_request_minimize(struct wl_listener *listener, void *data) {
|
||||
struct sway_xwayland_view *xwayland_view =
|
||||
wl_container_of(listener, xwayland_view, request_minimize);
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
if (!xsurface->mapped) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_xwayland_minimize_event *e = data;
|
||||
struct sway_seat *seat = input_manager_current_seat();
|
||||
bool focused = seat_get_focus(seat) == &view->container->node;
|
||||
wlr_xwayland_surface_set_minimized(xsurface, !focused && e->minimize);
|
||||
}
|
||||
|
||||
static void handle_request_move(struct wl_listener *listener, void *data) {
|
||||
struct sway_xwayland_view *xwayland_view =
|
||||
wl_container_of(listener, xwayland_view, request_move);
|
||||
|
|
@ -653,6 +674,10 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
|
|||
&xwayland_view->request_fullscreen);
|
||||
xwayland_view->request_fullscreen.notify = handle_request_fullscreen;
|
||||
|
||||
wl_signal_add(&xsurface->events.request_minimize,
|
||||
&xwayland_view->request_minimize);
|
||||
xwayland_view->request_minimize.notify = handle_request_minimize;
|
||||
|
||||
wl_signal_add(&xsurface->events.request_activate,
|
||||
&xwayland_view->request_activate);
|
||||
xwayland_view->request_activate.notify = handle_request_activate;
|
||||
|
|
|
|||
|
|
@ -99,8 +99,8 @@ struct sway_node *node_at_coords(
|
|||
return NULL;
|
||||
}
|
||||
struct sway_output *output = wlr_output->data;
|
||||
if (!output || !output->configured) {
|
||||
// output is being destroyed or is being configured
|
||||
if (!output || !output->enabled) {
|
||||
// output is being destroyed or is being enabled
|
||||
return NULL;
|
||||
}
|
||||
double ox = lx, oy = ly;
|
||||
|
|
@ -1244,6 +1244,10 @@ static void warp_to_constraint_cursor_hint(struct sway_cursor *cursor) {
|
|||
double ly = sy + con->content_y - view->geometry.y;
|
||||
|
||||
wlr_cursor_warp(cursor->cursor, NULL, lx, ly);
|
||||
|
||||
// Warp the pointer as well, so that on the next pointer rebase we don't
|
||||
// send an unexpected synthetic motion event to clients.
|
||||
wlr_seat_pointer_warp(constraint->seat, sx, sy);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ static bool set_send_events(struct libinput_device *device, uint32_t mode) {
|
|||
if (libinput_device_config_send_events_get_mode(device) == mode) {
|
||||
return false;
|
||||
}
|
||||
sway_log(SWAY_DEBUG, "send_events_set_mode(%d)", mode);
|
||||
sway_log(SWAY_DEBUG, "send_events_set_mode(%" PRIu32 ")", mode);
|
||||
log_status(libinput_device_config_send_events_set_mode(device, mode));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -150,7 +150,7 @@ static bool set_scroll_button(struct libinput_device *dev, uint32_t button) {
|
|||
libinput_device_config_scroll_get_button(dev) == button) {
|
||||
return false;
|
||||
}
|
||||
sway_log(SWAY_DEBUG, "scroll_set_button(%d)", button);
|
||||
sway_log(SWAY_DEBUG, "scroll_set_button(%" PRIu32 ")", button);
|
||||
log_status(libinput_device_config_scroll_set_button(dev, button));
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -470,31 +470,29 @@ static void handle_start_drag(struct wl_listener *listener, void *data) {
|
|||
wl_signal_add(&wlr_drag->events.destroy, &drag->destroy);
|
||||
|
||||
struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon;
|
||||
if (wlr_drag_icon == NULL) {
|
||||
return;
|
||||
if (wlr_drag_icon != NULL) {
|
||||
struct sway_drag_icon *icon = calloc(1, sizeof(struct sway_drag_icon));
|
||||
if (icon == NULL) {
|
||||
sway_log(SWAY_ERROR, "Allocation failed");
|
||||
return;
|
||||
}
|
||||
icon->seat = seat;
|
||||
icon->wlr_drag_icon = wlr_drag_icon;
|
||||
wlr_drag_icon->data = icon;
|
||||
|
||||
icon->surface_commit.notify = drag_icon_handle_surface_commit;
|
||||
wl_signal_add(&wlr_drag_icon->surface->events.commit, &icon->surface_commit);
|
||||
icon->unmap.notify = drag_icon_handle_unmap;
|
||||
wl_signal_add(&wlr_drag_icon->events.unmap, &icon->unmap);
|
||||
icon->map.notify = drag_icon_handle_map;
|
||||
wl_signal_add(&wlr_drag_icon->events.map, &icon->map);
|
||||
icon->destroy.notify = drag_icon_handle_destroy;
|
||||
wl_signal_add(&wlr_drag_icon->events.destroy, &icon->destroy);
|
||||
|
||||
wl_list_insert(&root->drag_icons, &icon->link);
|
||||
|
||||
drag_icon_update_position(icon);
|
||||
}
|
||||
|
||||
struct sway_drag_icon *icon = calloc(1, sizeof(struct sway_drag_icon));
|
||||
if (icon == NULL) {
|
||||
sway_log(SWAY_ERROR, "Allocation failed");
|
||||
return;
|
||||
}
|
||||
icon->seat = seat;
|
||||
icon->wlr_drag_icon = wlr_drag_icon;
|
||||
wlr_drag_icon->data = icon;
|
||||
|
||||
icon->surface_commit.notify = drag_icon_handle_surface_commit;
|
||||
wl_signal_add(&wlr_drag_icon->surface->events.commit, &icon->surface_commit);
|
||||
icon->unmap.notify = drag_icon_handle_unmap;
|
||||
wl_signal_add(&wlr_drag_icon->events.unmap, &icon->unmap);
|
||||
icon->map.notify = drag_icon_handle_map;
|
||||
wl_signal_add(&wlr_drag_icon->events.map, &icon->map);
|
||||
icon->destroy.notify = drag_icon_handle_destroy;
|
||||
wl_signal_add(&wlr_drag_icon->events.destroy, &icon->destroy);
|
||||
|
||||
wl_list_insert(&root->drag_icons, &icon->link);
|
||||
|
||||
drag_icon_update_position(icon);
|
||||
seatop_begin_default(seat);
|
||||
}
|
||||
|
||||
|
|
@ -918,7 +916,7 @@ void seat_configure_xcursor(struct sway_seat *seat) {
|
|||
|
||||
if (seat == input_manager_get_default_seat()) {
|
||||
char cursor_size_fmt[16];
|
||||
snprintf(cursor_size_fmt, sizeof(cursor_size_fmt), "%d", cursor_size);
|
||||
snprintf(cursor_size_fmt, sizeof(cursor_size_fmt), "%u", cursor_size);
|
||||
setenv("XCURSOR_SIZE", cursor_size_fmt, 1);
|
||||
if (cursor_theme != NULL) {
|
||||
setenv("XCURSOR_THEME", cursor_theme, 1);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,12 @@ struct seatop_resize_floating_event {
|
|||
static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
||||
struct wlr_input_device *device, uint32_t button,
|
||||
enum wlr_button_state state) {
|
||||
struct seatop_resize_floating_event *e = seat->seatop_data;
|
||||
struct sway_container *con = e->con;
|
||||
|
||||
if (seat->cursor->pressed_button_count == 0) {
|
||||
container_set_resizing(con, false);
|
||||
arrange_container(con); // Send configure w/o resizing hint
|
||||
seatop_begin_default(seat);
|
||||
}
|
||||
}
|
||||
|
|
@ -170,6 +175,7 @@ void seatop_begin_resize_floating(struct sway_seat *seat,
|
|||
seat->seatop_impl = &seatop_impl;
|
||||
seat->seatop_data = e;
|
||||
|
||||
container_set_resizing(con, true);
|
||||
container_raise_floating(con);
|
||||
|
||||
const char *image = edge == WLR_EDGE_NONE ?
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
#include "sway/commands.h"
|
||||
#include "sway/input/cursor.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/view.h"
|
||||
|
||||
struct seatop_resize_tiling_event {
|
||||
struct sway_container *con; // leaf container
|
||||
|
|
@ -12,6 +15,10 @@ struct seatop_resize_tiling_event {
|
|||
struct sway_container *h_con;
|
||||
struct sway_container *v_con;
|
||||
|
||||
// sibling con(s) that will be resized to accommodate
|
||||
struct sway_container *h_sib;
|
||||
struct sway_container *v_sib;
|
||||
|
||||
enum wlr_edges edge;
|
||||
enum wlr_edges edge_x, edge_y;
|
||||
double ref_lx, ref_ly; // cursor's x/y at start of op
|
||||
|
|
@ -19,10 +26,47 @@ struct seatop_resize_tiling_event {
|
|||
double v_con_orig_height; // height of the vertical ancestor at start
|
||||
};
|
||||
|
||||
static struct sway_container *container_get_resize_sibling(
|
||||
struct sway_container *con, uint32_t edge) {
|
||||
if (!con) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_t *siblings = container_get_siblings(con);
|
||||
int index = container_sibling_index(con);
|
||||
int offset = edge & (WLR_EDGE_TOP | WLR_EDGE_LEFT) ? -1 : 1;
|
||||
|
||||
if (siblings->length == 1) {
|
||||
return NULL;
|
||||
} else {
|
||||
return siblings->items[index + offset];
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
||||
struct wlr_input_device *device, uint32_t button,
|
||||
enum wlr_button_state state) {
|
||||
struct seatop_resize_tiling_event *e = seat->seatop_data;
|
||||
|
||||
if (seat->cursor->pressed_button_count == 0) {
|
||||
if (e->h_con) {
|
||||
container_set_resizing(e->h_con, false);
|
||||
container_set_resizing(e->h_sib, false);
|
||||
if (e->h_con->parent) {
|
||||
arrange_container(e->h_con->parent);
|
||||
} else {
|
||||
arrange_workspace(e->h_con->workspace);
|
||||
}
|
||||
}
|
||||
if (e->v_con) {
|
||||
container_set_resizing(e->v_con, false);
|
||||
container_set_resizing(e->v_sib, false);
|
||||
if (e->v_con->parent) {
|
||||
arrange_container(e->v_con->parent);
|
||||
} else {
|
||||
arrange_workspace(e->v_con->workspace);
|
||||
}
|
||||
}
|
||||
seatop_begin_default(seat);
|
||||
}
|
||||
}
|
||||
|
|
@ -89,16 +133,22 @@ void seatop_begin_resize_tiling(struct sway_seat *seat,
|
|||
if (edge & (WLR_EDGE_LEFT | WLR_EDGE_RIGHT)) {
|
||||
e->edge_x = edge & (WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
|
||||
e->h_con = container_find_resize_parent(e->con, e->edge_x);
|
||||
e->h_sib = container_get_resize_sibling(e->h_con, e->edge_x);
|
||||
|
||||
if (e->h_con) {
|
||||
container_set_resizing(e->h_con, true);
|
||||
container_set_resizing(e->h_sib, true);
|
||||
e->h_con_orig_width = e->h_con->width;
|
||||
}
|
||||
}
|
||||
if (edge & (WLR_EDGE_TOP | WLR_EDGE_BOTTOM)) {
|
||||
e->edge_y = edge & (WLR_EDGE_TOP | WLR_EDGE_BOTTOM);
|
||||
e->v_con = container_find_resize_parent(e->con, e->edge_y);
|
||||
e->v_sib = container_get_resize_sibling(e->v_con, e->edge_y);
|
||||
|
||||
if (e->v_con) {
|
||||
container_set_resizing(e->v_con, true);
|
||||
container_set_resizing(e->v_sib, true);
|
||||
e->v_con_orig_height = e->v_con->height;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ json_object *ipc_json_get_version(void) {
|
|||
int major = 0, minor = 0, patch = 0;
|
||||
json_object *version = json_object_new_object();
|
||||
|
||||
sscanf(SWAY_VERSION, "%u.%u.%u", &major, &minor, &patch);
|
||||
sscanf(SWAY_VERSION, "%d.%d.%d", &major, &minor, &patch);
|
||||
|
||||
json_object_object_add(version, "human_readable", json_object_new_string(SWAY_VERSION));
|
||||
json_object_object_add(version, "variant", json_object_new_string("sway"));
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ struct sockaddr_un *ipc_user_sockaddr(void) {
|
|||
dir = "/tmp";
|
||||
}
|
||||
if (path_size <= snprintf(ipc_sockaddr->sun_path, path_size,
|
||||
"%s/sway-ipc.%i.%i.sock", dir, getuid(), getpid())) {
|
||||
"%s/sway-ipc.%u.%i.sock", dir, getuid(), getpid())) {
|
||||
sway_abort("Socket path won't fit into ipc_sockaddr->sun_path");
|
||||
}
|
||||
|
||||
|
|
@ -242,7 +242,6 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) {
|
|||
}
|
||||
|
||||
uint8_t buf[IPC_HEADER_SIZE];
|
||||
uint32_t *buf32 = (uint32_t*)(buf + sizeof(ipc_magic));
|
||||
// Should be fully available, because read_available >= IPC_HEADER_SIZE
|
||||
ssize_t received = recv(client_fd, buf, IPC_HEADER_SIZE, 0);
|
||||
if (received == -1) {
|
||||
|
|
@ -257,8 +256,8 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&client->pending_length, &buf32[0], sizeof(buf32[0]));
|
||||
memcpy(&client->pending_type, &buf32[1], sizeof(buf32[1]));
|
||||
memcpy(&client->pending_length, buf + sizeof(ipc_magic), sizeof(uint32_t));
|
||||
memcpy(&client->pending_type, buf + sizeof(ipc_magic) + sizeof(uint32_t), sizeof(uint32_t));
|
||||
|
||||
if (read_available - received >= (long)client->pending_length) {
|
||||
// Reset pending values.
|
||||
|
|
@ -920,11 +919,10 @@ bool ipc_send_reply(struct ipc_client *client, enum ipc_command_type payload_typ
|
|||
assert(payload);
|
||||
|
||||
char data[IPC_HEADER_SIZE];
|
||||
uint32_t *data32 = (uint32_t*)(data + sizeof(ipc_magic));
|
||||
|
||||
memcpy(data, ipc_magic, sizeof(ipc_magic));
|
||||
memcpy(&data32[0], &payload_length, sizeof(payload_length));
|
||||
memcpy(&data32[1], &payload_type, sizeof(payload_type));
|
||||
memcpy(data + sizeof(ipc_magic), &payload_length, sizeof(payload_length));
|
||||
memcpy(data + sizeof(ipc_magic) + sizeof(payload_length), &payload_type, sizeof(payload_type));
|
||||
|
||||
while (client->write_buffer_len + IPC_HEADER_SIZE + payload_length >=
|
||||
client->write_buffer_size) {
|
||||
|
|
|
|||
|
|
@ -138,7 +138,8 @@ static void log_env(void) {
|
|||
"SWAYSOCK",
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(log_vars) / sizeof(char *); ++i) {
|
||||
sway_log(SWAY_INFO, "%s=%s", log_vars[i], getenv(log_vars[i]));
|
||||
char *value = getenv(log_vars[i]);
|
||||
sway_log(SWAY_INFO, "%s=%s", log_vars[i], value != NULL ? value : "");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -215,9 +215,11 @@ set|plus|minus <amount>
|
|||
If unspecified, the default is 10 pixels. Pixels are ignored when moving
|
||||
tiled containers.
|
||||
|
||||
*move* [absolute] position <pos_x> [px] <pos_y> [px]
|
||||
Moves the focused container to the specified position in the workspace. If
|
||||
_absolute_ is used, the position is relative to all outputs.
|
||||
*move* [absolute] position <pos_x> [px|ppt] <pos_y> [px|ptt]
|
||||
Moves the focused container to the specified position in the workspace.
|
||||
The position can be specified in pixels or percentage points, omitting
|
||||
the unit defaults to pixels. If _absolute_ is used, the position is
|
||||
relative to all outputs. _absolute_ can not be used with percentage points.
|
||||
|
||||
*move* [absolute] position center
|
||||
Moves the focused container to be centered on the workspace. If _absolute_
|
||||
|
|
@ -272,7 +274,9 @@ set|plus|minus <amount>
|
|||
optional comment argument is ignored, but logged for debugging purposes.
|
||||
|
||||
*reload*
|
||||
Reloads the sway config file and applies any changes.
|
||||
Reloads the sway config file and applies any changes. The config file is
|
||||
located at path specified by the command line arguments when started,
|
||||
otherwise according to the priority stated in *sway*(1).
|
||||
|
||||
*rename workspace* [<old_name>] to <new_name>
|
||||
Rename either <old_name> or the focused workspace to the <new_name>
|
||||
|
|
@ -304,7 +308,7 @@ set|plus|minus <amount>
|
|||
Shows a window from the scratchpad. Repeatedly using this command will
|
||||
cycle through the windows in the scratchpad.
|
||||
|
||||
*shortcuts inhibitor* enable|disable
|
||||
*shortcuts_inhibitor* enable|disable
|
||||
Enables or disables the ability of clients to inhibit keyboard
|
||||
shortcuts for a view. This is primarily useful for virtualization and
|
||||
remote desktop software. It affects either the currently focused view
|
||||
|
|
|
|||
|
|
@ -746,6 +746,28 @@ void container_floating_set_default_size(struct sway_container *con) {
|
|||
free(box);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicate to clients in this container that they are participating in (or
|
||||
* have just finished) an interactive resize
|
||||
*/
|
||||
void container_set_resizing(struct sway_container *con, bool resizing) {
|
||||
if (!con) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (con->view) {
|
||||
if (con->view->impl->set_resizing) {
|
||||
con->view->impl->set_resizing(con->view, resizing);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < con->children->length; ++i ) {
|
||||
struct sway_container *child = con->children->items[i];
|
||||
container_set_resizing(child, resizing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void container_set_floating(struct sway_container *container, bool enable) {
|
||||
if (container_is_floating(container) == enable) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -110,12 +110,12 @@ struct sway_output *output_create(struct wlr_output *wlr_output) {
|
|||
return output;
|
||||
}
|
||||
|
||||
void output_configure(struct sway_output *output) {
|
||||
if (!sway_assert(!output->configured, "output is already configured")) {
|
||||
void output_enable(struct sway_output *output) {
|
||||
if (!sway_assert(!output->enabled, "output is already enabled")) {
|
||||
return;
|
||||
}
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
output->configured = true;
|
||||
output->enabled = true;
|
||||
list_add(root->outputs, output);
|
||||
|
||||
restore_workspaces(output);
|
||||
|
|
@ -251,6 +251,11 @@ void output_disable(struct sway_output *output) {
|
|||
if (!sway_assert(output->enabled, "Expected an enabled output")) {
|
||||
return;
|
||||
}
|
||||
int index = list_find(root->outputs, output);
|
||||
if (!sway_assert(index >= 0, "Output not found in root node")) {
|
||||
return;
|
||||
}
|
||||
|
||||
sway_log(SWAY_DEBUG, "Disabling output '%s'", output->wlr_output->name);
|
||||
wl_signal_emit(&output->events.destroy, output);
|
||||
|
||||
|
|
@ -258,11 +263,9 @@ void output_disable(struct sway_output *output) {
|
|||
|
||||
root_for_each_container(untrack_output, output);
|
||||
|
||||
int index = list_find(root->outputs, output);
|
||||
list_del(root->outputs, index);
|
||||
|
||||
output->enabled = false;
|
||||
output->configured = false;
|
||||
output->current_mode = NULL;
|
||||
|
||||
arrange_root();
|
||||
|
|
|
|||
|
|
@ -625,7 +625,12 @@ static void handle_foreign_activate_request(
|
|||
struct sway_seat *seat;
|
||||
wl_list_for_each(seat, &server.input->seats, link) {
|
||||
if (seat->wlr_seat == event->seat) {
|
||||
if (container_is_scratchpad_hidden_or_child(view->container)) {
|
||||
root_scratchpad_show(view->container);
|
||||
}
|
||||
seat_set_focus_container(seat, view->container);
|
||||
seat_consider_warp_to_focus(seat);
|
||||
container_raise_floating(view->container);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ struct status_line *status_line_init(char *cmd) {
|
|||
|
||||
void status_line_free(struct status_line *status) {
|
||||
status_line_close_fds(status);
|
||||
kill(status->pid, status->cont_signal);
|
||||
kill(status->pid, SIGTERM);
|
||||
waitpid(status->pid, NULL, 0);
|
||||
if (status->protocol == PROTOCOL_I3BAR) {
|
||||
|
|
|
|||
|
|
@ -44,12 +44,18 @@ _swaymsg_ [options...] [message]
|
|||
The message is a sway command (the same commands you can bind to keybindings
|
||||
in your sway config file). It will be executed immediately.
|
||||
|
||||
See **sway**(5) for a list of commands.
|
||||
See *sway*(5) for a list of commands.
|
||||
|
||||
Tip: If you are proving a command that contains a leading hyphen (_-_),
|
||||
insert two hyphens (_--_) before the command to signal to swaymsg not to
|
||||
parse anything beyond that point as an option. For example, use
|
||||
_swaymsg -- mark --add test_ instead of _swaymsg mark --add test_
|
||||
Tips:
|
||||
- Command expansion is performed twice: once by swaymsg, and again by sway.
|
||||
If you have quoted multi-word strings in your command, enclose the entire
|
||||
command in single-quotes. For example, use
|
||||
_swaymsg 'output "Foobar Display" enable'_ instead of
|
||||
_swaymsg output "Foobar Display" enable_.
|
||||
- If you are proving a command that contains a leading hyphen (_-_), insert
|
||||
two hyphens (_--_) before the command to signal to swaymsg not to parse
|
||||
anything beyond that point as an option. For example, use
|
||||
_swaymsg -- mark --add test_ instead of _swaymsg mark --add test_.
|
||||
|
||||
*get\_workspaces*
|
||||
Gets a JSON-encoded list of workspaces and their status.
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
sway_log(SWAY_DEBUG, "Output: %s", swaynag.type->output);
|
||||
sway_log(SWAY_DEBUG, "Anchors: %d", swaynag.type->anchors);
|
||||
sway_log(SWAY_DEBUG, "Anchors: %" PRIu32, swaynag.type->anchors);
|
||||
sway_log(SWAY_DEBUG, "Type: %s", swaynag.type->name);
|
||||
sway_log(SWAY_DEBUG, "Message: %s", swaynag.message);
|
||||
sway_log(SWAY_DEBUG, "Font: %s", swaynag.type->font);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue