Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions metadata/workarounds.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,10 @@
<min>0</min>
<max>500</max>
</option>
<option name="force_xwayland_scaling" type="bool">
<_short>Force Xwayland DPI scaling</_short>
<_long>Disables the default blurry scaling for Xwayland and forces client-side scaling for Xwayland windows dependent on the DPI settings.</_long>
<default>false</default>
</option>
</plugin>
</wayfire>
2 changes: 1 addition & 1 deletion plugins/common/move-drag-interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ bool core_drag_t::is_view_held_in_place()
void core_drag_t::update_current_output(wf::point_t grab)
{
wf::pointf_t origin = {1.0 * grab.x, 1.0 * grab.y};
auto output = wf::get_core().output_layout->get_output_coords_at(origin, origin);
auto output = wf::get_core().output_layout->find_closest_output(origin);
update_current_output(output);
}

Expand Down
2 changes: 1 addition & 1 deletion plugins/single_plugins/alpha.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class wayfire_alpha : public wf::plugin_interface_t
wf::axis_callback axis_cb = [=] (wlr_pointer_axis_event *ev)
{
auto gc = wf::get_core().get_cursor_position();
auto current_output = wf::get_core().output_layout->get_output_coords_at(gc, gc);
auto current_output = wf::get_core().output_layout->find_closest_output(gc);
if (!current_output || !current_output->can_activate_plugin(&grab_interface))
{
return false;
Expand Down
2 changes: 1 addition & 1 deletion plugins/single_plugins/extra-gestures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class extra_gestures_plugin_t : public per_output_plugin_instance_t
auto center_touch_point = state.get_center().current;
wf::pointf_t center = {center_touch_point.x, center_touch_point.y};

if (core.output_layout->get_output_at(center.x, center.y) != this->output)
if (core.output_layout->find_closest_output(center) != this->output)
{
return;
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/single_plugins/move.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ class wayfire_move : public wf::per_output_plugin_instance_t,
bool initiate(wayfire_toplevel_view view, wf::point_t grab_position)
{
// First, make sure that the view is on the output the input is.
auto target_output = wf::get_core().output_layout->get_output_at(grab_position.x, grab_position.y);
auto target_output = wf::get_core().output_layout->find_closest_output(wf::pointf_t{grab_position});
if (target_output && (view->get_output() != target_output))
{
auto parent = wf::find_topmost_parent(view);
Expand Down
1 change: 0 additions & 1 deletion src/api/wayfire/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ class compositor_core_t : public wf::object_base_t, public signal::provider_t
wlr_export_dmabuf_manager_v1 *export_dmabuf;
wlr_server_decoration_manager *decorator_manager;
wlr_xdg_decoration_manager_v1 *xdg_decorator;
wlr_xdg_output_manager_v1 *output_manager;
wlr_virtual_keyboard_manager_v1 *vkbd_manager;
wlr_virtual_pointer_manager_v1 *vptr_manager;
wlr_input_inhibit_manager *input_inhibit;
Expand Down
1 change: 0 additions & 1 deletion src/api/wayfire/nonstd/wlroots-full.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ extern "C"
#include <wlr/types/wlr_output_power_management_v1.h>
#endif
#include <wlr/types/wlr_gamma_control_v1.h>
#include <wlr/types/wlr_xdg_output_v1.h>
#include <wlr/types/wlr_drm_lease_v1.h>

// Input
Expand Down
67 changes: 38 additions & 29 deletions src/api/wayfire/output-layout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,12 @@ struct output_state_t
/** An output configuration is simply a list of each output with its state */
using output_configuration_t = std::map<wlr_output*, output_state_t>;

/* output_layout_t is responsible for managing outputs and their attributes -
* mode, scale, position, transform. */
/**
* The output layout is a manager for all outputs in the compositor.
*
* It keeps track of all outputs reported by the wlroots backend (DRM connectors, wayland-backend nested
* outputs, etc.), as well as a virtual NOOP output for cases where no other outputs are present.
*/
class output_layout_t : public wf::signal::provider_t
{
public:
Expand All @@ -158,48 +162,53 @@ class output_layout_t : public wf::signal::provider_t
wlr_output_layout *get_handle();

/**
* @return the output at the given coordinates, or null if no such output
*/
wf::output_t *get_output_at(int x, int y);

/**
* Get the output closest to the given origin and the closest coordinates
* to origin which lie inside the output.
* Generate a list of the active outputs in the output layout.
* Here an active output is an output which is enabled (potentially in DPMS mode) and not mirrored.
* Such outputs have a corresponding logical wf::output_t object allocated to them.
*
* @param origin The start coordinates
* @param closest The closest point to origin inside the returned output
* @return the output at the given coordinates
*/
wf::output_t *get_output_coords_at(wf::pointf_t origin, wf::pointf_t& closest);

/**
* @return the number of the active outputs in the output layout
* In case that no outputs are present or enabled, the list will contain the NOOP output.
*
* @return a list of the active outputs in the output layout
*/
size_t get_num_outputs();
std::vector<wf::output_t*> get_outputs();

/**
* @return a list of the active outputs in the output layout
* Find the active output which is closest to the given coordinates.
*
* @param origin The coordinates to find the closest output to
* @return The output closest to @origin
*/
std::vector<wf::output_t*> get_outputs();
wf::output_t *find_closest_output(wf::pointf_t origin);

/**
* @return the "next" output in the layout. It is guaranteed that starting
* with any output in the layout, and successively calling this function
* will iterate over all outputs
* Find the active output which is closest to the given coordinates.
*
* @param origin The coordinates to find the closest output to
* @param closest Output parameter to store the coordinates of the closest point on the output found
* @return The output closest to @origin
*/
wf::output_t *get_next_output(wf::output_t *output);
wf::output_t *find_closest_output(wf::pointf_t origin, wf::pointf_t& closest);

/**
* @return the output_t associated with the wlr_output, or null if the
* output isn't found
*/
wf::output_t *find_output(wlr_output *output);

/**
* @return the output_t with the given name, or null if not found
*/
wf::output_t *find_output(std::string name);

/**
* @return the current output configuration. This contains ALL outputs,
* not just the ones in the actual layout (so disabled ones are included
* as well)
* Get the current output configuration, consisting of every present output regardless of its state (i.e
* including disabled and mirrored outputs).
*
* Note that the output configuration includes only outputs reported by the wlroots backend. The NOOP
* output is never included here, even if it is the only present / enabled output.
* Thus, the output configuration may be empty even if get_outputs() returns a non-empty list.
*
* @return The current output configuration
*/
output_configuration_t get_current_configuration();

Expand All @@ -211,8 +220,8 @@ class output_layout_t : public wf::signal::provider_t
* outputs to their previous state.
*
* @param configuration The output configuration to be applied
* @param test_only If true, this will only simulate applying
* the configuration, without actually changing anything
* @param test_only If true, this will only simulate applying the configuration, without actually
* changing anything
*
* @return true on successful application, false otherwise
*/
Expand Down
5 changes: 5 additions & 0 deletions src/api/wayfire/output.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ class output_t : public wf::object_base_t, public wf::signal::provider_t
*/
wf::geometry_t get_layout_geometry() const;

/**
* Returns the current output scale.
*/
float get_scale() const;

/**
* Moves the pointer so that it is inside the output
*
Expand Down
2 changes: 1 addition & 1 deletion src/api/wayfire/plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ using wayfire_plugin_load_func = wf::plugin_interface_t * (*)();
/**
* The version is defined as macro as well, to allow conditional compilation.
*/
#define WAYFIRE_API_ABI_VERSION_MACRO 2025'12'26
#define WAYFIRE_API_ABI_VERSION_MACRO 2026'01'12

/**
* The version of Wayfire's API/ABI
Expand Down
5 changes: 4 additions & 1 deletion src/api/wayfire/unstable/wlr-surface-node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct surface_state_t
wlr_texture *texture; // The texture of the wlr_client_buffer

wf::region_t accumulated_damage;
wf::region_t opaque_region;
wf::dimensions_t size = {0, 0};
std::optional<wlr_fbox> src_viewport;
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
Expand Down Expand Up @@ -69,7 +70,7 @@ class wlr_surface_node_t : public node_t, public zero_copy_texturable_node_t
std::optional<wf::texture_t> to_texture() const override;

wlr_surface *get_surface() const;
void apply_state(surface_state_t&& state);
virtual void apply_state(surface_state_t&& state);
void apply_current_surface_state();
void send_frame_done(bool delay_until_vblank);

Expand All @@ -92,6 +93,8 @@ class wlr_surface_node_t : public node_t, public zero_copy_texturable_node_t
wf::wl_listener_wrapper on_surface_commit;

const bool autocommit;

protected:
surface_state_t current_state;
};
}
Expand Down
8 changes: 7 additions & 1 deletion src/api/wayfire/unstable/xwl-toplevel-base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@

#include <wayfire/nonstd/wlroots-full.hpp>
#include <wayfire/view.hpp>
#include <wayfire/util.hpp>
#include <wayfire/unstable/wlr-surface-node.hpp>

namespace wf
{
#if WF_HAS_XWAYLAND
namespace xw
{
class xwayland_surface_node_t;
}

/**
* A base class for views which base on a wlr_xwayland surface.
* Contains the implementation of view_interface_t functions used in them.
Expand Down Expand Up @@ -50,7 +56,7 @@ class xwayland_view_base_t : public virtual wf::view_interface_t
void handle_title_changed(std::string new_title);

wf::wl_listener_wrapper on_destroy, on_set_title, on_set_app_id, on_ping_timeout;
std::shared_ptr<wf::scene::wlr_surface_node_t> main_surface;
std::shared_ptr<wf::xw::xwayland_surface_node_t> main_surface;
};
#endif
}
2 changes: 2 additions & 0 deletions src/core/core-impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "wayfire/scene.hpp"
#include "wayfire/util.hpp"
#include <wayfire/nonstd/wlroots-full.hpp>
#include "src/core/xdg-output-management.hpp"

namespace wf
{
Expand All @@ -24,6 +25,7 @@ class compositor_core_impl_t : public compositor_core_t
std::unique_ptr<wf::input_manager_t> input;
std::unique_ptr<input_method_relay> im_relay;
std::unique_ptr<plugin_manager_t> plugin_mgr;
std::unique_ptr<wf::xdg_output_manager_v1> xdg_output_manager;

/**
* Initialize the compositor core.
Expand Down
9 changes: 4 additions & 5 deletions src/core/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ void wf::compositor_core_impl_t::init()
protocols.image_copy_capture = wlr_ext_image_copy_capture_manager_v1_create(display, 1);
protocols.image_capture_source = wlr_ext_output_image_capture_source_manager_v1_create(display, 1);
protocols.gamma_v1 = wlr_gamma_control_manager_v1_create(display);
protocols.export_dmabuf = wlr_export_dmabuf_manager_v1_create(display);
protocols.output_manager = wlr_xdg_output_manager_v1_create(display,
output_layout->get_handle());
protocols.export_dmabuf = wlr_export_dmabuf_manager_v1_create(display);
xdg_output_manager = std::make_unique<wf::xdg_output_manager_v1>(display,
output_layout.get());
protocols.drm_v1 = wlr_drm_lease_v1_manager_create(display, backend);
drm_lease_request.set_callback([&] (void *data)
{
Expand Down Expand Up @@ -294,8 +294,7 @@ void wf::compositor_core_impl_t::post_init()

this->state = compositor_state_t::RUNNING;
// Move pointer to the middle of the leftmost, topmost output
wf::pointf_t p;
wf::output_t *wo = wf::get_core().output_layout->get_output_coords_at({FLT_MIN, FLT_MIN}, p);
wf::output_t *wo = output_layout->find_closest_output({FLT_MIN, FLT_MIN});
// Output might be noop but guaranteed to not be null
wo->ensure_pointer(true);
seat->focus_output(wo);
Expand Down
64 changes: 19 additions & 45 deletions src/core/output-layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,8 +635,18 @@ struct output_layout_output_t
bool shutdown = is_shutting_down();
if ((get_core().seat->get_active_output() == wo) && !shutdown)
{
get_core().seat->focus_output(
get_core().output_layout->get_next_output(wo));
auto outputs = get_core().output_layout->get_outputs();
wf::dassert(!outputs.empty(),
"There should be at least one output left if we're not shutting down");

auto it = std::find(outputs.begin(), outputs.end(), wo);
if ((it == outputs.end()) || (std::next(it) == outputs.end()))
{
get_core().seat->focus_output(outputs[0]);
} else
{
get_core().seat->focus_output(*(std::next(it)));
}
} else if (shutdown)
{
get_core().seat->focus_output(nullptr);
Expand Down Expand Up @@ -1798,11 +1808,6 @@ class output_layout_t::impl
return output_layout;
}

size_t get_num_outputs()
{
return get_outputs().size();
}

wf::output_t *find_output(wlr_output *output)
{
if (outputs.count(output))
Expand Down Expand Up @@ -1855,28 +1860,13 @@ class output_layout_t::impl
return result;
}

wf::output_t *get_next_output(wf::output_t *output)
{
auto os = get_outputs();

auto it = std::find(os.begin(), os.end(), output);
if ((it == os.end()) || (std::next(it) == os.end()))
{
return os[0];
} else
{
return *(++it);
}
}

wf::output_t *get_output_coords_at(const wf::pointf_t& origin,
wf::output_t *find_closest_output(const wf::pointf_t& origin,
wf::pointf_t& closest)
{
wlr_output_layout_closest_point(output_layout, NULL,
origin.x, origin.y, &closest.x, &closest.y);

auto handle =
wlr_output_layout_output_at(output_layout, closest.x, closest.y);
auto handle = wlr_output_layout_output_at(output_layout, closest.x, closest.y);
assert(handle || is_shutting_down());
if (!handle)
{
Expand All @@ -1892,13 +1882,6 @@ class output_layout_t::impl
}
}

wf::output_t *get_output_at(int x, int y)
{
wf::pointf_t dummy;

return get_output_coords_at({1.0 * x, 1.0 * y}, dummy);
}

bool apply_configuration(const output_configuration_t& configuration,
bool test_only)
{
Expand All @@ -1922,32 +1905,23 @@ wlr_output_layout*output_layout_t::get_handle()
return pimpl->get_handle();
}

wf::output_t*output_layout_t::get_output_at(int x, int y)
wf::output_t*output_layout_t::find_closest_output(wf::pointf_t point)
{
return pimpl->get_output_at(x, y);
wf::pointf_t dummy;
return find_closest_output(point, dummy);
}

wf::output_t*output_layout_t::get_output_coords_at(wf::pointf_t origin,
wf::output_t*output_layout_t::find_closest_output(wf::pointf_t origin,
wf::pointf_t& closest)
{
return pimpl->get_output_coords_at(origin, closest);
}

size_t output_layout_t::get_num_outputs()
{
return pimpl->get_num_outputs();
return pimpl->find_closest_output(origin, closest);
}

std::vector<wf::output_t*> output_layout_t::get_outputs()
{
return pimpl->get_outputs();
}

wf::output_t*output_layout_t::get_next_output(wf::output_t *output)
{
return pimpl->get_next_output(output);
}

wf::output_t*output_layout_t::find_output(wlr_output *output)
{
return pimpl->find_output(output);
Expand Down
Loading