mirror of
https://github.com/swaywm/sway.git
synced 2025-01-30 20:56:43 +00:00
Merge branch 'master' into sensitivity
This commit is contained in:
commit
81cecd3b04
12
README.de.md
12
README.de.md
|
@ -2,13 +2,13 @@
|
|||
Sway ist ein [i3](https://i3wm.org/)-kompatibler [Wayland](http://wayland.freedesktop.org/)-Compositor. Lies die [FAQ](https://github.com/swaywm/sway/wiki). Tritt dem [IRC Channel](https://web.libera.chat/gamja/?channels=#sway) bei (#sway on irc.libera.chat; Englisch).
|
||||
|
||||
## Signaturen
|
||||
Jedes Release wird mit dem PGP-Schlüssel [E88F5E48](https://keys.openpgp.org/search?q=34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48) signiert und auf GitHub veröffentlicht.
|
||||
Jedes Release wird mit dem PGP-Schlüssel [E88F5E48](https://keys.openpgp.org/search?q=34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48) signiert und [auf GitHub](https://github.com/swaywm/sway/releases) veröffentlicht.
|
||||
|
||||
## Installation
|
||||
### Mit der Paketverwaltung
|
||||
Sway kann in vielen Distributionen direkt durch die Paketverwaltung installiert werden. Das Paket sollte "sway" heißen. Falls es kein solches Paket gibt, kannst du im [Wiki](https://github.com/swaywm/sway/wiki/Unsupported-packages) (englisch) nach mehr Informationen bezüglich deiner Distribution suchen.
|
||||
|
||||
Falls du sway für deine eigene Distribution als Paket bereitstellen möchtest, solltest du die Entwickler per IRC oder E-Mail (sir@cmpwn.com) kontaktieren.
|
||||
### Über die Paketverwaltung
|
||||
|
||||
Sway kann in vielen Distributionen direkt durch die Paketverwaltung installiert werden. Versuche einfach das Packet "sway" zu installieren.
|
||||
|
||||
### Quellcode selbst kompilieren
|
||||
|
||||
|
@ -23,8 +23,8 @@ sway benötigt die folgenden Pakete:
|
|||
* pango
|
||||
* cairo
|
||||
* gdk-pixbuf2 (Optional, wird für das Benachrichtigungsfeld (System Tray) benötigt)
|
||||
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc)\* (Optional, wird für die Dokumentation (Man Pages) benötigt)
|
||||
* git\*
|
||||
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (Optional, wird für die Dokumentation (Man Pages) benötigt)\*
|
||||
* git (Optional: Versionsinfo)\*
|
||||
|
||||
_\*Werden nur während des Kompilierens benötigt_
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
lib_sway_common = static_library(
|
||||
'sway-common',
|
||||
files(
|
||||
'background-image.c',
|
||||
'cairo.c',
|
||||
'gesture.c',
|
||||
'ipc-client.c',
|
||||
|
@ -14,7 +13,6 @@ lib_sway_common = static_library(
|
|||
),
|
||||
dependencies: [
|
||||
cairo,
|
||||
gdk_pixbuf,
|
||||
pango,
|
||||
pangocairo,
|
||||
wayland_client.partial_dependency(compile_args: true)
|
||||
|
|
|
@ -205,7 +205,7 @@ bar {
|
|||
|
||||
# When the status_command prints a new line to stdout, swaybar updates.
|
||||
# The default just shows the current date and time.
|
||||
status_command while date +'%Y-%m-%d %I:%M:%S %p'; do sleep 1; done
|
||||
status_command while date +'%Y-%m-%d %X'; do sleep 1; done
|
||||
|
||||
colors {
|
||||
statusline #ffffff
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef _SWAY_BACKGROUND_IMAGE_H
|
||||
#define _SWAY_BACKGROUND_IMAGE_H
|
||||
#include "cairo_util.h"
|
||||
|
||||
enum background_mode {
|
||||
BACKGROUND_MODE_STRETCH,
|
||||
BACKGROUND_MODE_FILL,
|
||||
BACKGROUND_MODE_FIT,
|
||||
BACKGROUND_MODE_CENTER,
|
||||
BACKGROUND_MODE_TILE,
|
||||
BACKGROUND_MODE_SOLID_COLOR,
|
||||
BACKGROUND_MODE_INVALID,
|
||||
};
|
||||
|
||||
enum background_mode parse_background_mode(const char *mode);
|
||||
cairo_surface_t *load_background_image(const char *path);
|
||||
void render_background_image(cairo_t *cairo, cairo_surface_t *image,
|
||||
enum background_mode mode, int buffer_width, int buffer_height);
|
||||
|
||||
#endif
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef _SWAY_INPUT_INPUT_MANAGER_H
|
||||
#define _SWAY_INPUT_INPUT_MANAGER_H
|
||||
#include <libinput.h>
|
||||
#include <wlr/types/wlr_input_inhibitor.h>
|
||||
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
|
||||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||
|
@ -21,7 +20,6 @@ struct sway_input_manager {
|
|||
struct wl_list devices;
|
||||
struct wl_list seats;
|
||||
|
||||
struct wlr_input_inhibit_manager *inhibit;
|
||||
struct wlr_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit;
|
||||
struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard;
|
||||
struct wlr_virtual_pointer_manager_v1 *virtual_pointer;
|
||||
|
|
|
@ -59,7 +59,7 @@ struct sway_server {
|
|||
struct wl_listener layer_shell_surface;
|
||||
|
||||
struct wlr_xdg_shell *xdg_shell;
|
||||
struct wl_listener xdg_shell_surface;
|
||||
struct wl_listener xdg_shell_toplevel;
|
||||
|
||||
struct wlr_tablet_manager_v2 *tablet_v2;
|
||||
|
||||
|
@ -114,6 +114,10 @@ struct sway_server {
|
|||
struct wlr_text_input_manager_v3 *text_input;
|
||||
struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
|
||||
struct wlr_content_type_manager_v1 *content_type_manager_v1;
|
||||
struct wlr_data_control_manager_v1 *data_control_manager_v1;
|
||||
struct wlr_screencopy_manager_v1 *screencopy_manager_v1;
|
||||
struct wlr_export_dmabuf_manager_v1 *export_dmabuf_manager_v1;
|
||||
struct wlr_security_context_manager_v1 *security_context_manager_v1;
|
||||
|
||||
struct wlr_xdg_activation_v1 *xdg_activation_v1;
|
||||
struct wl_listener xdg_activation_v1_request_activate;
|
||||
|
@ -172,7 +176,7 @@ void handle_new_output(struct wl_listener *listener, void *data);
|
|||
void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data);
|
||||
void handle_layer_shell_surface(struct wl_listener *listener, void *data);
|
||||
void sway_session_lock_init(void);
|
||||
void handle_xdg_shell_surface(struct wl_listener *listener, void *data);
|
||||
void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data);
|
||||
#if HAVE_XWAYLAND
|
||||
void handle_xwayland_surface(struct wl_listener *listener, void *data);
|
||||
#endif
|
||||
|
|
|
@ -41,7 +41,7 @@ struct sway_root {
|
|||
} events;
|
||||
};
|
||||
|
||||
struct sway_root *root_create(void);
|
||||
struct sway_root *root_create(struct wl_display *display);
|
||||
|
||||
void root_destroy(struct sway_root *root);
|
||||
|
||||
|
|
|
@ -226,6 +226,7 @@ struct sway_xdg_popup {
|
|||
|
||||
struct wlr_xdg_popup *wlr_xdg_popup;
|
||||
|
||||
struct wl_listener surface_commit;
|
||||
struct wl_listener new_popup;
|
||||
struct wl_listener destroy;
|
||||
};
|
||||
|
|
|
@ -16,4 +16,6 @@ struct sway_xdg_decoration {
|
|||
struct sway_xdg_decoration *xdg_decoration_from_surface(
|
||||
struct wlr_surface *surface);
|
||||
|
||||
void set_xdg_decoration_mode(struct sway_xdg_decoration *deco);
|
||||
|
||||
#endif
|
||||
|
|
7
include/swaybar/image.h
Normal file
7
include/swaybar/image.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef _SWAYBAR_IMAGE_H
|
||||
#define _SWAYBAR_IMAGE_H
|
||||
#include <cairo.h>
|
||||
|
||||
cairo_surface_t *load_image(const char *path);
|
||||
|
||||
#endif
|
|
@ -37,7 +37,7 @@ if is_freebsd
|
|||
endif
|
||||
|
||||
# Execute the wlroots subproject, if any
|
||||
wlroots_version = ['>=0.17.0', '<0.18.0']
|
||||
wlroots_version = ['>=0.18.0', '<0.19.0']
|
||||
subproject(
|
||||
'wlroots',
|
||||
default_options: ['examples=false'],
|
||||
|
|
|
@ -16,7 +16,6 @@ protocols = [
|
|||
wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
|
||||
'wlr-layer-shell-unstable-v1.xml',
|
||||
'idle.xml',
|
||||
'wlr-input-inhibitor-unstable-v1.xml',
|
||||
'wlr-output-power-management-unstable-v1.xml',
|
||||
]
|
||||
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="wlr_input_inhibit_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2018 Drew DeVault
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that copyright notice and this permission
|
||||
notice appear in supporting documentation, and that the name of
|
||||
the copyright holders not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific,
|
||||
written prior permission. The copyright holders make no
|
||||
representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied
|
||||
warranty.
|
||||
|
||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zwlr_input_inhibit_manager_v1" version="1">
|
||||
<description summary="inhibits input events to other clients">
|
||||
Clients can use this interface to prevent input events from being sent to
|
||||
any surfaces but its own, which is useful for example in lock screen
|
||||
software. It is assumed that access to this interface will be locked down
|
||||
to whitelisted clients by the compositor.
|
||||
</description>
|
||||
|
||||
<request name="get_inhibitor">
|
||||
<description summary="inhibit input to other clients">
|
||||
Activates the input inhibitor. As long as the inhibitor is active, the
|
||||
compositor will not send input events to other clients.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zwlr_input_inhibitor_v1"/>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="already_inhibited" value="0" summary="an input inhibitor is already in use on the compositor"/>
|
||||
</enum>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_input_inhibitor_v1" version="1">
|
||||
<description summary="inhibits input to other clients">
|
||||
While this resource exists, input to clients other than the owner of the
|
||||
inhibitor resource will not receive input events. The client that owns
|
||||
this resource will receive all input events normally. The compositor will
|
||||
also disable all of its own input processing (such as keyboard shortcuts)
|
||||
while the inhibitor is active.
|
||||
|
||||
The compositor may continue to send input events to selected clients,
|
||||
such as an on-screen keyboard (via the input-method protocol).
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the input inhibitor object">
|
||||
Destroy the inhibitor and allow other clients to receive input.
|
||||
</description>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
|
@ -1,4 +1,5 @@
|
|||
#include <string.h>
|
||||
#include <wlr/util/transform.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
#include "log.h"
|
||||
|
|
|
@ -975,7 +975,7 @@ char *do_var_replacement(char *str) {
|
|||
int offset = find - str;
|
||||
strncpy(newptr, str, offset);
|
||||
newptr += offset;
|
||||
strncpy(newptr, var->value, vvlen);
|
||||
memcpy(newptr, var->value, vvlen);
|
||||
newptr += vvlen;
|
||||
strcpy(newptr, find + vnlen);
|
||||
free(str);
|
||||
|
|
|
@ -542,36 +542,6 @@ static void popup_damage(struct sway_layer_popup *layer_popup, bool whole) {
|
|||
output_damage_surface(output, ox, oy, surface, whole);
|
||||
}
|
||||
|
||||
static void popup_handle_map(struct wl_listener *listener, void *data) {
|
||||
struct sway_layer_popup *popup = wl_container_of(listener, popup, map);
|
||||
struct sway_layer_surface *layer = popup_get_layer(popup);
|
||||
struct wlr_output *wlr_output = layer->layer_surface->output;
|
||||
sway_assert(wlr_output, "wlr_layer_surface_v1 has null output");
|
||||
surface_enter_output(popup->wlr_popup->base->surface, wlr_output->data);
|
||||
popup_damage(popup, true);
|
||||
}
|
||||
|
||||
static void popup_handle_unmap(struct wl_listener *listener, void *data) {
|
||||
struct sway_layer_popup *popup = wl_container_of(listener, popup, unmap);
|
||||
popup_damage(popup, true);
|
||||
}
|
||||
|
||||
static void popup_handle_commit(struct wl_listener *listener, void *data) {
|
||||
struct sway_layer_popup *popup = wl_container_of(listener, popup, commit);
|
||||
popup_damage(popup, false);
|
||||
}
|
||||
|
||||
static void popup_handle_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_layer_popup *popup =
|
||||
wl_container_of(listener, popup, destroy);
|
||||
|
||||
wl_list_remove(&popup->map.link);
|
||||
wl_list_remove(&popup->unmap.link);
|
||||
wl_list_remove(&popup->destroy.link);
|
||||
wl_list_remove(&popup->commit.link);
|
||||
free(popup);
|
||||
}
|
||||
|
||||
static void popup_unconstrain(struct sway_layer_popup *popup) {
|
||||
struct sway_layer_surface *layer = popup_get_layer(popup);
|
||||
struct wlr_xdg_popup *wlr_popup = popup->wlr_popup;
|
||||
|
@ -592,6 +562,39 @@ static void popup_unconstrain(struct sway_layer_popup *popup) {
|
|||
wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box);
|
||||
}
|
||||
|
||||
static void popup_handle_map(struct wl_listener *listener, void *data) {
|
||||
struct sway_layer_popup *popup = wl_container_of(listener, popup, map);
|
||||
struct sway_layer_surface *layer = popup_get_layer(popup);
|
||||
struct wlr_output *wlr_output = layer->layer_surface->output;
|
||||
sway_assert(wlr_output, "wlr_layer_surface_v1 has null output");
|
||||
surface_enter_output(popup->wlr_popup->base->surface, wlr_output->data);
|
||||
popup_damage(popup, true);
|
||||
}
|
||||
|
||||
static void popup_handle_unmap(struct wl_listener *listener, void *data) {
|
||||
struct sway_layer_popup *popup = wl_container_of(listener, popup, unmap);
|
||||
popup_damage(popup, true);
|
||||
}
|
||||
|
||||
static void popup_handle_commit(struct wl_listener *listener, void *data) {
|
||||
struct sway_layer_popup *popup = wl_container_of(listener, popup, commit);
|
||||
if (popup->wlr_popup->base->initial_commit) {
|
||||
popup_unconstrain(popup);
|
||||
}
|
||||
popup_damage(popup, false);
|
||||
}
|
||||
|
||||
static void popup_handle_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_layer_popup *popup =
|
||||
wl_container_of(listener, popup, destroy);
|
||||
|
||||
wl_list_remove(&popup->map.link);
|
||||
wl_list_remove(&popup->unmap.link);
|
||||
wl_list_remove(&popup->destroy.link);
|
||||
wl_list_remove(&popup->commit.link);
|
||||
free(popup);
|
||||
}
|
||||
|
||||
static void popup_handle_new_popup(struct wl_listener *listener, void *data);
|
||||
|
||||
static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup,
|
||||
|
@ -617,8 +620,6 @@ static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup,
|
|||
popup->new_popup.notify = popup_handle_new_popup;
|
||||
wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup);
|
||||
|
||||
popup_unconstrain(popup);
|
||||
|
||||
return popup;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <wlr/types/wlr_presentation_time.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/util/region.h>
|
||||
#include <wlr/util/transform.h>
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
#include "sway/config.h"
|
||||
|
@ -964,6 +965,11 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
|||
wlr_damage_ring_set_bounds(&output->damage_ring, width, height);
|
||||
wlr_output_schedule_frame(output->wlr_output);
|
||||
}
|
||||
|
||||
// Next time the output is enabled, try to re-apply the gamma LUT
|
||||
if ((event->state->committed & WLR_OUTPUT_STATE_ENABLED) && !output->wlr_output->enabled) {
|
||||
output->gamma_lut_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_present(struct wl_listener *listener, void *data) {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/util/region.h>
|
||||
#include <wlr/util/transform.h>
|
||||
#include "log.h"
|
||||
#include "config.h"
|
||||
#include "sway/config.h"
|
||||
|
|
|
@ -38,6 +38,7 @@ static void popup_destroy(struct sway_view_child *child) {
|
|||
return;
|
||||
}
|
||||
struct sway_xdg_popup *popup = (struct sway_xdg_popup *)child;
|
||||
wl_list_remove(&popup->surface_commit.link);
|
||||
wl_list_remove(&popup->new_popup.link);
|
||||
wl_list_remove(&popup->destroy.link);
|
||||
free(popup);
|
||||
|
@ -51,18 +52,6 @@ static const struct sway_view_child_impl popup_impl = {
|
|||
static struct sway_xdg_popup *popup_create(
|
||||
struct wlr_xdg_popup *wlr_popup, struct sway_view *view);
|
||||
|
||||
static void popup_handle_new_popup(struct wl_listener *listener, void *data) {
|
||||
struct sway_xdg_popup *popup =
|
||||
wl_container_of(listener, popup, new_popup);
|
||||
struct wlr_xdg_popup *wlr_popup = data;
|
||||
popup_create(wlr_popup, popup->child.view);
|
||||
}
|
||||
|
||||
static void popup_handle_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_xdg_popup *popup = wl_container_of(listener, popup, destroy);
|
||||
view_child_destroy(&popup->child);
|
||||
}
|
||||
|
||||
static void popup_unconstrain(struct sway_xdg_popup *popup) {
|
||||
struct sway_view *view = popup->child.view;
|
||||
struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_popup;
|
||||
|
@ -87,6 +76,25 @@ static void popup_unconstrain(struct sway_xdg_popup *popup) {
|
|||
wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box);
|
||||
}
|
||||
|
||||
static void popup_handle_surface_commit(struct wl_listener *listener, void *data) {
|
||||
struct sway_xdg_popup *popup = wl_container_of(listener, popup, surface_commit);
|
||||
if (popup->wlr_xdg_popup->base->initial_commit) {
|
||||
popup_unconstrain(popup);
|
||||
}
|
||||
}
|
||||
|
||||
static void popup_handle_new_popup(struct wl_listener *listener, void *data) {
|
||||
struct sway_xdg_popup *popup =
|
||||
wl_container_of(listener, popup, new_popup);
|
||||
struct wlr_xdg_popup *wlr_popup = data;
|
||||
popup_create(wlr_popup, popup->child.view);
|
||||
}
|
||||
|
||||
static void popup_handle_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_xdg_popup *popup = wl_container_of(listener, popup, destroy);
|
||||
view_child_destroy(&popup->child);
|
||||
}
|
||||
|
||||
static struct sway_xdg_popup *popup_create(
|
||||
struct wlr_xdg_popup *wlr_popup, struct sway_view *view) {
|
||||
struct wlr_xdg_surface *xdg_surface = wlr_popup->base;
|
||||
|
@ -97,22 +105,21 @@ static struct sway_xdg_popup *popup_create(
|
|||
return NULL;
|
||||
}
|
||||
view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface);
|
||||
popup->wlr_xdg_popup = xdg_surface->popup;
|
||||
popup->wlr_xdg_popup = wlr_popup;
|
||||
|
||||
wl_signal_add(&xdg_surface->surface->events.commit, &popup->surface_commit);
|
||||
popup->surface_commit.notify = popup_handle_surface_commit;
|
||||
wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup);
|
||||
popup->new_popup.notify = popup_handle_new_popup;
|
||||
wl_signal_add(&xdg_surface->events.destroy, &popup->destroy);
|
||||
wl_signal_add(&wlr_popup->events.destroy, &popup->destroy);
|
||||
popup->destroy.notify = popup_handle_destroy;
|
||||
|
||||
wl_signal_add(&xdg_surface->surface->events.map, &popup->child.surface_map);
|
||||
wl_signal_add(&xdg_surface->surface->events.unmap, &popup->child.surface_unmap);
|
||||
|
||||
popup_unconstrain(popup);
|
||||
|
||||
return popup;
|
||||
}
|
||||
|
||||
|
||||
static struct sway_xdg_shell_view *xdg_shell_view_from_view(
|
||||
struct sway_view *view) {
|
||||
if (!sway_assert(view->type == SWAY_VIEW_XDG_SHELL,
|
||||
|
@ -286,6 +293,19 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
|||
struct sway_view *view = &xdg_shell_view->view;
|
||||
struct wlr_xdg_surface *xdg_surface = view->wlr_xdg_toplevel->base;
|
||||
|
||||
if (xdg_surface->initial_commit) {
|
||||
if (view->xdg_decoration != NULL) {
|
||||
set_xdg_decoration_mode(view->xdg_decoration);
|
||||
}
|
||||
// XXX: https://github.com/swaywm/sway/issues/2176
|
||||
wlr_xdg_surface_schedule_configure(xdg_surface);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!xdg_surface->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_box new_geo;
|
||||
wlr_xdg_surface_get_geometry(xdg_surface, &new_geo);
|
||||
bool new_size = new_geo.width != view->geometry.width ||
|
||||
|
@ -421,7 +441,6 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
|
|||
|
||||
view_unmap(view);
|
||||
|
||||
wl_list_remove(&xdg_shell_view->commit.link);
|
||||
wl_list_remove(&xdg_shell_view->new_popup.link);
|
||||
wl_list_remove(&xdg_shell_view->request_maximize.link);
|
||||
wl_list_remove(&xdg_shell_view->request_fullscreen.link);
|
||||
|
@ -464,10 +483,6 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
|||
|
||||
transaction_commit_dirty();
|
||||
|
||||
xdg_shell_view->commit.notify = handle_commit;
|
||||
wl_signal_add(&toplevel->base->surface->events.commit,
|
||||
&xdg_shell_view->commit);
|
||||
|
||||
xdg_shell_view->new_popup.notify = handle_new_popup;
|
||||
wl_signal_add(&toplevel->base->events.new_popup,
|
||||
&xdg_shell_view->new_popup);
|
||||
|
@ -507,6 +522,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
|||
wl_list_remove(&xdg_shell_view->destroy.link);
|
||||
wl_list_remove(&xdg_shell_view->map.link);
|
||||
wl_list_remove(&xdg_shell_view->unmap.link);
|
||||
wl_list_remove(&xdg_shell_view->commit.link);
|
||||
view->wlr_xdg_toplevel = NULL;
|
||||
if (view->xdg_decoration) {
|
||||
view->xdg_decoration->view = NULL;
|
||||
|
@ -519,17 +535,12 @@ struct sway_view *view_from_wlr_xdg_surface(
|
|||
return xdg_surface->data;
|
||||
}
|
||||
|
||||
void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xdg_surface *xdg_surface = data;
|
||||
|
||||
if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
|
||||
sway_log(SWAY_DEBUG, "New xdg_shell popup");
|
||||
return;
|
||||
}
|
||||
void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xdg_toplevel *xdg_toplevel = data;
|
||||
|
||||
sway_log(SWAY_DEBUG, "New xdg_shell toplevel title='%s' app_id='%s'",
|
||||
xdg_surface->toplevel->title, xdg_surface->toplevel->app_id);
|
||||
wlr_xdg_surface_ping(xdg_surface);
|
||||
xdg_toplevel->title, xdg_toplevel->app_id);
|
||||
wlr_xdg_surface_ping(xdg_toplevel->base);
|
||||
|
||||
struct sway_xdg_shell_view *xdg_shell_view =
|
||||
calloc(1, sizeof(struct sway_xdg_shell_view));
|
||||
|
@ -538,16 +549,20 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
view_init(&xdg_shell_view->view, SWAY_VIEW_XDG_SHELL, &view_impl);
|
||||
xdg_shell_view->view.wlr_xdg_toplevel = xdg_surface->toplevel;
|
||||
xdg_shell_view->view.wlr_xdg_toplevel = xdg_toplevel;
|
||||
|
||||
xdg_shell_view->map.notify = handle_map;
|
||||
wl_signal_add(&xdg_surface->surface->events.map, &xdg_shell_view->map);
|
||||
wl_signal_add(&xdg_toplevel->base->surface->events.map, &xdg_shell_view->map);
|
||||
|
||||
xdg_shell_view->unmap.notify = handle_unmap;
|
||||
wl_signal_add(&xdg_surface->surface->events.unmap, &xdg_shell_view->unmap);
|
||||
wl_signal_add(&xdg_toplevel->base->surface->events.unmap, &xdg_shell_view->unmap);
|
||||
|
||||
xdg_shell_view->commit.notify = handle_commit;
|
||||
wl_signal_add(&xdg_toplevel->base->surface->events.commit,
|
||||
&xdg_shell_view->commit);
|
||||
|
||||
xdg_shell_view->destroy.notify = handle_destroy;
|
||||
wl_signal_add(&xdg_surface->events.destroy, &xdg_shell_view->destroy);
|
||||
wl_signal_add(&xdg_toplevel->events.destroy, &xdg_shell_view->destroy);
|
||||
|
||||
xdg_surface->data = xdg_shell_view;
|
||||
xdg_toplevel->base->data = xdg_shell_view;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <wlr/config.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_keyboard_group.h>
|
||||
#include <wlr/types/wlr_input_inhibitor.h>
|
||||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||
#include "sway/config.h"
|
||||
|
@ -284,34 +283,6 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
}
|
||||
|
||||
static void handle_inhibit_activate(struct wl_listener *listener, void *data) {
|
||||
struct sway_input_manager *input_manager = wl_container_of(
|
||||
listener, input_manager, inhibit_activate);
|
||||
struct sway_seat *seat;
|
||||
wl_list_for_each(seat, &input_manager->seats, link) {
|
||||
seat_set_exclusive_client(seat, input_manager->inhibit->active_client);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_inhibit_deactivate(struct wl_listener *listener, void *data) {
|
||||
struct sway_input_manager *input_manager = wl_container_of(
|
||||
listener, input_manager, inhibit_deactivate);
|
||||
struct sway_seat *seat;
|
||||
if (server.session_lock.locked) {
|
||||
// Don't deactivate the grab of a screenlocker
|
||||
return;
|
||||
}
|
||||
wl_list_for_each(seat, &input_manager->seats, link) {
|
||||
seat_set_exclusive_client(seat, NULL);
|
||||
struct sway_node *previous = seat_get_focus(seat);
|
||||
if (previous) {
|
||||
// Hack to get seat to re-focus the return value of get_focus
|
||||
seat_set_focus(seat, NULL);
|
||||
seat_set_focus(seat, previous);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_keyboard_shortcuts_inhibitor_destroy(
|
||||
struct wl_listener *listener, void *data) {
|
||||
struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor =
|
||||
|
@ -480,14 +451,6 @@ struct sway_input_manager *input_manager_create(struct sway_server *server) {
|
|||
&input->virtual_pointer_new);
|
||||
input->virtual_pointer_new.notify = handle_virtual_pointer;
|
||||
|
||||
input->inhibit = wlr_input_inhibit_manager_create(server->wl_display);
|
||||
input->inhibit_activate.notify = handle_inhibit_activate;
|
||||
wl_signal_add(&input->inhibit->events.activate,
|
||||
&input->inhibit_activate);
|
||||
input->inhibit_deactivate.notify = handle_inhibit_deactivate;
|
||||
wl_signal_add(&input->inhibit->events.deactivate,
|
||||
&input->inhibit_deactivate);
|
||||
|
||||
input->keyboard_shortcuts_inhibit =
|
||||
wlr_keyboard_shortcuts_inhibit_v1_create(server->wl_display);
|
||||
input->keyboard_shortcuts_inhibit_new_inhibitor.notify =
|
||||
|
|
|
@ -375,8 +375,6 @@ int main(int argc, char **argv) {
|
|||
|
||||
sway_log(SWAY_INFO, "Starting sway version " SWAY_VERSION);
|
||||
|
||||
root = root_create();
|
||||
|
||||
if (!server_init(&server)) {
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
#include <wlr/types/wlr_primary_selection_v1.h>
|
||||
#include <wlr/types/wlr_relative_pointer_v1.h>
|
||||
#include <wlr/types/wlr_screencopy_v1.h>
|
||||
#include <wlr/types/wlr_single_pixel_buffer_v1.h>
|
||||
#include <wlr/types/wlr_security_context_v1.h>
|
||||
#include <wlr/types/wlr_server_decoration.h>
|
||||
#include <wlr/types/wlr_single_pixel_buffer_v1.h>
|
||||
#include <wlr/types/wlr_subcompositor.h>
|
||||
#include <wlr/types/wlr_tablet_v2.h>
|
||||
#include <wlr/types/wlr_viewporter.h>
|
||||
|
@ -73,6 +74,24 @@ static void handle_drm_lease_request(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool is_privileged(const struct wl_global *global) {
|
||||
return
|
||||
global == server.output_manager_v1->global ||
|
||||
global == server.output_power_manager_v1->global ||
|
||||
global == server.input_method->global ||
|
||||
global == server.foreign_toplevel_manager->global ||
|
||||
global == server.data_control_manager_v1->global ||
|
||||
global == server.screencopy_manager_v1->global ||
|
||||
global == server.export_dmabuf_manager_v1->global ||
|
||||
global == server.security_context_manager_v1->global ||
|
||||
global == server.gamma_control_manager_v1->global ||
|
||||
global == server.layer_shell->global ||
|
||||
global == server.session_lock.manager->global ||
|
||||
global == server.input->keyboard_shortcuts_inhibit->global ||
|
||||
global == server.input->virtual_keyboard->global ||
|
||||
global == server.input->virtual_pointer->global;
|
||||
}
|
||||
|
||||
static bool filter_global(const struct wl_client *client,
|
||||
const struct wl_global *global, void *data) {
|
||||
#if HAVE_XWAYLAND
|
||||
|
@ -82,6 +101,15 @@ static bool filter_global(const struct wl_client *client,
|
|||
}
|
||||
#endif
|
||||
|
||||
// Restrict usage of privileged protocols to unsandboxed clients
|
||||
// TODO: add a way for users to configure an allow-list
|
||||
const struct wlr_security_context_v1_state *security_context =
|
||||
wlr_security_context_manager_v1_lookup_client(
|
||||
server.security_context_manager_v1, (struct wl_client *)client);
|
||||
if (is_privileged(global)) {
|
||||
return security_context == NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -92,6 +120,8 @@ bool server_init(struct sway_server *server) {
|
|||
|
||||
wl_display_set_global_filter(server->wl_display, filter_global, NULL);
|
||||
|
||||
root = root_create(server->wl_display);
|
||||
|
||||
server->backend = wlr_backend_autocreate(server->wl_display, &server->session);
|
||||
if (!server->backend) {
|
||||
sway_log(SWAY_ERROR, "Unable to create backend");
|
||||
|
@ -155,9 +185,9 @@ bool server_init(struct sway_server *server) {
|
|||
|
||||
server->xdg_shell = wlr_xdg_shell_create(server->wl_display,
|
||||
SWAY_XDG_SHELL_VERSION);
|
||||
wl_signal_add(&server->xdg_shell->events.new_surface,
|
||||
&server->xdg_shell_surface);
|
||||
server->xdg_shell_surface.notify = handle_xdg_shell_surface;
|
||||
wl_signal_add(&server->xdg_shell->events.new_toplevel,
|
||||
&server->xdg_shell_toplevel);
|
||||
server->xdg_shell_toplevel.notify = handle_xdg_shell_toplevel;
|
||||
|
||||
server->tablet_v2 = wlr_tablet_v2_create(server->wl_display);
|
||||
|
||||
|
@ -226,9 +256,10 @@ bool server_init(struct sway_server *server) {
|
|||
}
|
||||
#endif
|
||||
|
||||
wlr_export_dmabuf_manager_v1_create(server->wl_display);
|
||||
wlr_screencopy_manager_v1_create(server->wl_display);
|
||||
wlr_data_control_manager_v1_create(server->wl_display);
|
||||
server->export_dmabuf_manager_v1 = wlr_export_dmabuf_manager_v1_create(server->wl_display);
|
||||
server->screencopy_manager_v1 = wlr_screencopy_manager_v1_create(server->wl_display);
|
||||
server->data_control_manager_v1 = wlr_data_control_manager_v1_create(server->wl_display);
|
||||
server->security_context_manager_v1 = wlr_security_context_manager_v1_create(server->wl_display);
|
||||
wlr_viewporter_create(server->wl_display);
|
||||
wlr_single_pixel_buffer_manager_v1_create(server->wl_display);
|
||||
server->content_type_manager_v1 =
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/util/transform.h>
|
||||
#include "sway/desktop/transaction.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/ipc-server.h"
|
||||
|
@ -23,14 +24,14 @@ static void output_layout_handle_change(struct wl_listener *listener,
|
|||
transaction_commit_dirty();
|
||||
}
|
||||
|
||||
struct sway_root *root_create(void) {
|
||||
struct sway_root *root_create(struct wl_display *wl_display) {
|
||||
struct sway_root *root = calloc(1, sizeof(struct sway_root));
|
||||
if (!root) {
|
||||
sway_log(SWAY_ERROR, "Unable to allocate sway_root");
|
||||
return NULL;
|
||||
}
|
||||
node_init(&root->node, N_ROOT, root);
|
||||
root->output_layout = wlr_output_layout_create();
|
||||
root->output_layout = wlr_output_layout_create(wl_display);
|
||||
wl_list_init(&root->all_outputs);
|
||||
#if HAVE_XWAYLAND
|
||||
wl_list_init(&root->xwayland_unmanaged);
|
||||
|
@ -52,7 +53,6 @@ void root_destroy(struct sway_root *root) {
|
|||
list_free(root->scratchpad);
|
||||
list_free(root->non_desktop_outputs);
|
||||
list_free(root->outputs);
|
||||
wlr_output_layout_destroy(root->output_layout);
|
||||
free(root);
|
||||
}
|
||||
|
||||
|
|
|
@ -882,6 +882,8 @@ void view_unmap(struct sway_view *view) {
|
|||
|
||||
wl_list_remove(&view->surface_new_subsurface.link);
|
||||
|
||||
view->executed_criteria->length = 0;
|
||||
|
||||
if (view->urgent_timer) {
|
||||
wl_event_source_remove(view->urgent_timer);
|
||||
view->urgent_timer = NULL;
|
||||
|
|
|
@ -23,6 +23,45 @@ static void xdg_decoration_handle_request_mode(struct wl_listener *listener,
|
|||
void *data) {
|
||||
struct sway_xdg_decoration *deco =
|
||||
wl_container_of(listener, deco, request_mode);
|
||||
set_xdg_decoration_mode(deco);
|
||||
}
|
||||
|
||||
void handle_xdg_decoration(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xdg_toplevel_decoration_v1 *wlr_deco = data;
|
||||
struct sway_xdg_shell_view *xdg_shell_view = wlr_deco->toplevel->base->data;
|
||||
|
||||
struct sway_xdg_decoration *deco = calloc(1, sizeof(*deco));
|
||||
if (deco == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
deco->view = &xdg_shell_view->view;
|
||||
deco->view->xdg_decoration = deco;
|
||||
deco->wlr_xdg_decoration = wlr_deco;
|
||||
|
||||
wl_signal_add(&wlr_deco->events.destroy, &deco->destroy);
|
||||
deco->destroy.notify = xdg_decoration_handle_destroy;
|
||||
|
||||
wl_signal_add(&wlr_deco->events.request_mode, &deco->request_mode);
|
||||
deco->request_mode.notify = xdg_decoration_handle_request_mode;
|
||||
|
||||
wl_list_insert(&server.xdg_decorations, &deco->link);
|
||||
|
||||
set_xdg_decoration_mode(deco);
|
||||
}
|
||||
|
||||
struct sway_xdg_decoration *xdg_decoration_from_surface(
|
||||
struct wlr_surface *surface) {
|
||||
struct sway_xdg_decoration *deco;
|
||||
wl_list_for_each(deco, &server.xdg_decorations, link) {
|
||||
if (deco->wlr_xdg_decoration->toplevel->base->surface == surface) {
|
||||
return deco;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void set_xdg_decoration_mode(struct sway_xdg_decoration *deco) {
|
||||
struct sway_view *view = deco->view;
|
||||
enum wlr_xdg_toplevel_decoration_v1_mode mode =
|
||||
WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;
|
||||
|
@ -47,41 +86,7 @@ static void xdg_decoration_handle_request_mode(struct wl_listener *listener,
|
|||
mode = client_mode;
|
||||
}
|
||||
|
||||
wlr_xdg_toplevel_decoration_v1_set_mode(deco->wlr_xdg_decoration,
|
||||
mode);
|
||||
}
|
||||
|
||||
void handle_xdg_decoration(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xdg_toplevel_decoration_v1 *wlr_deco = data;
|
||||
struct sway_xdg_shell_view *xdg_shell_view = wlr_deco->toplevel->base->data;
|
||||
|
||||
struct sway_xdg_decoration *deco = calloc(1, sizeof(*deco));
|
||||
if (deco == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
deco->view = &xdg_shell_view->view;
|
||||
deco->view->xdg_decoration = deco;
|
||||
deco->wlr_xdg_decoration = wlr_deco;
|
||||
|
||||
wl_signal_add(&wlr_deco->events.destroy, &deco->destroy);
|
||||
deco->destroy.notify = xdg_decoration_handle_destroy;
|
||||
|
||||
wl_signal_add(&wlr_deco->events.request_mode, &deco->request_mode);
|
||||
deco->request_mode.notify = xdg_decoration_handle_request_mode;
|
||||
|
||||
wl_list_insert(&server.xdg_decorations, &deco->link);
|
||||
|
||||
xdg_decoration_handle_request_mode(&deco->request_mode, wlr_deco);
|
||||
}
|
||||
|
||||
struct sway_xdg_decoration *xdg_decoration_from_surface(
|
||||
struct wlr_surface *surface) {
|
||||
struct sway_xdg_decoration *deco;
|
||||
wl_list_for_each(deco, &server.xdg_decorations, link) {
|
||||
if (deco->wlr_xdg_decoration->toplevel->base->surface == surface) {
|
||||
return deco;
|
||||
if (view->wlr_xdg_toplevel->base->initialized) {
|
||||
wlr_xdg_toplevel_decoration_v1_set_mode(deco->wlr_xdg_decoration, mode);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,29 +1,12 @@
|
|||
#include <assert.h>
|
||||
#include "background-image.h"
|
||||
#include "cairo_util.h"
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
#include "swaybar/image.h"
|
||||
|
||||
#if HAVE_GDK_PIXBUF
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#endif
|
||||
|
||||
enum background_mode parse_background_mode(const char *mode) {
|
||||
if (strcmp(mode, "stretch") == 0) {
|
||||
return BACKGROUND_MODE_STRETCH;
|
||||
} else if (strcmp(mode, "fill") == 0) {
|
||||
return BACKGROUND_MODE_FILL;
|
||||
} else if (strcmp(mode, "fit") == 0) {
|
||||
return BACKGROUND_MODE_FIT;
|
||||
} else if (strcmp(mode, "center") == 0) {
|
||||
return BACKGROUND_MODE_CENTER;
|
||||
} else if (strcmp(mode, "tile") == 0) {
|
||||
return BACKGROUND_MODE_TILE;
|
||||
} else if (strcmp(mode, "solid_color") == 0) {
|
||||
return BACKGROUND_MODE_SOLID_COLOR;
|
||||
}
|
||||
sway_log(SWAY_ERROR, "Unsupported background mode: %s", mode);
|
||||
return BACKGROUND_MODE_INVALID;
|
||||
}
|
||||
|
||||
#if HAVE_GDK_PIXBUF
|
||||
static cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf(
|
||||
const GdkPixbuf *gdkbuf) {
|
||||
|
@ -121,7 +104,7 @@ static cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf(
|
|||
}
|
||||
#endif // HAVE_GDK_PIXBUF
|
||||
|
||||
cairo_surface_t *load_background_image(const char *path) {
|
||||
cairo_surface_t *load_image(const char *path) {
|
||||
cairo_surface_t *image;
|
||||
#if HAVE_GDK_PIXBUF
|
||||
GError *err = NULL;
|
||||
|
@ -151,70 +134,3 @@ cairo_surface_t *load_background_image(const char *path) {
|
|||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
void render_background_image(cairo_t *cairo, cairo_surface_t *image,
|
||||
enum background_mode mode, int buffer_width, int buffer_height) {
|
||||
double width = cairo_image_surface_get_width(image);
|
||||
double height = cairo_image_surface_get_height(image);
|
||||
|
||||
cairo_save(cairo);
|
||||
switch (mode) {
|
||||
case BACKGROUND_MODE_STRETCH:
|
||||
cairo_scale(cairo,
|
||||
(double)buffer_width / width,
|
||||
(double)buffer_height / height);
|
||||
cairo_set_source_surface(cairo, image, 0, 0);
|
||||
break;
|
||||
case BACKGROUND_MODE_FILL: {
|
||||
double window_ratio = (double)buffer_width / buffer_height;
|
||||
double bg_ratio = width / height;
|
||||
|
||||
if (window_ratio > bg_ratio) {
|
||||
double scale = (double)buffer_width / width;
|
||||
cairo_scale(cairo, scale, scale);
|
||||
cairo_set_source_surface(cairo, image,
|
||||
0, (double)buffer_height / 2 / scale - height / 2);
|
||||
} else {
|
||||
double scale = (double)buffer_height / height;
|
||||
cairo_scale(cairo, scale, scale);
|
||||
cairo_set_source_surface(cairo, image,
|
||||
(double)buffer_width / 2 / scale - width / 2, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BACKGROUND_MODE_FIT: {
|
||||
double window_ratio = (double)buffer_width / buffer_height;
|
||||
double bg_ratio = width / height;
|
||||
|
||||
if (window_ratio > bg_ratio) {
|
||||
double scale = (double)buffer_height / height;
|
||||
cairo_scale(cairo, scale, scale);
|
||||
cairo_set_source_surface(cairo, image,
|
||||
(double)buffer_width / 2 / scale - width / 2, 0);
|
||||
} else {
|
||||
double scale = (double)buffer_width / width;
|
||||
cairo_scale(cairo, scale, scale);
|
||||
cairo_set_source_surface(cairo, image,
|
||||
0, (double)buffer_height / 2 / scale - height / 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BACKGROUND_MODE_CENTER:
|
||||
cairo_set_source_surface(cairo, image,
|
||||
(double)buffer_width / 2 - width / 2,
|
||||
(double)buffer_height / 2 - height / 2);
|
||||
break;
|
||||
case BACKGROUND_MODE_TILE: {
|
||||
cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image);
|
||||
cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
|
||||
cairo_set_source(cairo, pattern);
|
||||
break;
|
||||
}
|
||||
case BACKGROUND_MODE_SOLID_COLOR:
|
||||
case BACKGROUND_MODE_INVALID:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
cairo_paint(cairo);
|
||||
cairo_restore(cairo);
|
||||
}
|
|
@ -26,6 +26,7 @@ executable(
|
|||
'bar.c',
|
||||
'config.c',
|
||||
'i3bar.c',
|
||||
'image.c',
|
||||
'input.c',
|
||||
'ipc.c',
|
||||
'main.c',
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
#include <string.h>
|
||||
#include "swaybar/bar.h"
|
||||
#include "swaybar/config.h"
|
||||
#include "swaybar/image.h"
|
||||
#include "swaybar/input.h"
|
||||
#include "swaybar/tray/host.h"
|
||||
#include "swaybar/tray/icon.h"
|
||||
#include "swaybar/tray/item.h"
|
||||
#include "swaybar/tray/tray.h"
|
||||
#include "background-image.h"
|
||||
#include "cairo_util.h"
|
||||
#include "list.h"
|
||||
#include "log.h"
|
||||
|
@ -431,7 +431,7 @@ static void reload_sni(struct swaybar_sni *sni, char *icon_theme,
|
|||
list_free(icon_search_paths);
|
||||
if (icon_path) {
|
||||
cairo_surface_destroy(sni->icon);
|
||||
sni->icon = load_background_image(icon_path);
|
||||
sni->icon = load_image(icon_path);
|
||||
free(icon_path);
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue