Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

more fixes #2335

Merged
merged 9 commits into from
Apr 17, 2024
10 changes: 8 additions & 2 deletions ipc-scripts/headless.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
add.add_argument('height', nargs='?', type=int, default=1080)

remove = subparsers.add_parser('remove')
remove.add_argument('output')
remove.add_argument('output', nargs='?', default=None)

args = parser.parse_args()
if args.action == "add":
Expand All @@ -25,7 +25,13 @@
print("Failed to create headless output: " + json.dumps(output, indent=4))

elif args.action == "remove":
if args.output.isdigit():
if args.output is None:
outputs = sock.list_outputs()
for o in outputs:
if 'HEADLESS' in o['name']:
print("Removing output " + o['name'] + " (" + str(o['id']) + ")")
print(sock.destroy_headless_output(output_id=o['id']))
elif args.output.isdigit():
print(sock.destroy_headless_output(output_id=int(args.output)))
else:
print(sock.destroy_headless_output(output_name=args.output))
Expand Down
3 changes: 3 additions & 0 deletions ipc-scripts/wayfire_socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ def query_output(self, output_id: int):
message["data"]["id"] = output_id
return self.send_json(message)

def list_outputs(self):
return self.send_json(get_msg_template("window-rules/list-outputs"))

def list_views(self):
return self.send_json(get_msg_template("window-rules/list-views"))

Expand Down
5 changes: 5 additions & 0 deletions plugins/common/wayfire/plugins/common/workspace-wall.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ class workspace_wall_t : public wf::signal::provider_t
}
}

wf::geometry_t get_viewport() const
{
return viewport;
}

/**
* Render the selected viewport on the framebuffer.
*
Expand Down
2 changes: 1 addition & 1 deletion plugins/ipc/ipc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ void wf::ipc::client_t::handle_fd_incoming(uint32_t event_mask)
}

const uint32_t len = *((uint32_t*)buffer.data());
if (len > MAX_MESSAGE_LEN - HEADER_LEN)
if (len > MAX_MESSAGE_LEN - HEADER_LEN + 1)
{
LOGE("Client tried to pass too long a message!");
ipc->client_disappeared(this);
Expand Down
62 changes: 50 additions & 12 deletions plugins/single_plugins/expo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,11 +372,36 @@ class wayfire_expo : public wf::per_output_plugin_instance_t, public wf::keyboar
*/
void handle_input_press(int32_t x, int32_t y, uint32_t state)
{
if (zoom_animation.running() || !this->state.active)
const bool zooming = zoom_animation.running();

if (!this->state.active)
{
return;
}

if (zooming && !this->state.zoom_in)
{
if (state == WLR_BUTTON_PRESSED)
{
// Zoom out of expo, change target workspace only
if (update_target_workspace(x, y))
{
output->wset()->set_workspace(target_ws);

// Calculate animation so that it appears as if we smoothly changed destination
wf::geometry_t cur_viewport = zoom_animation;
wf::geometry_t target_viewport = wall->get_workspace_rectangle(target_ws);
float cur_a = std::clamp(zoom_animation.progress(), 0.01, 0.99);
wf::geometry_t start_viewport = wf::interpolate(cur_viewport, target_viewport,
1.0 - 1.0 / (1.0 - cur_a));
zoom_animation.set_start(start_viewport);
zoom_animation.set_end(target_viewport);
}
}

return;
}

if ((state == WLR_BUTTON_RELEASED) && !this->drag_helper->view)
{
this->state.button_pressed = false;
Expand Down Expand Up @@ -622,26 +647,39 @@ class wayfire_expo : public wf::per_output_plugin_instance_t, public wf::keyboar
return wf::find_output_view_at(output, localf);
}

void update_target_workspace(int x, int y)
std::optional<wf::point_t> find_workspace_at(int x, int y)
{
auto og = output->get_layout_geometry();
wlr_box box = {x, y, 1, 1};
auto og = output->get_relative_geometry();
auto in_grid = wf::origin(wf::scale_box(og, wall->get_viewport(), box));

input_coordinates_to_global_coordinates(x, y);

auto grid = get_grid_geometry();
if (!(grid & wf::point_t{x, y}))
auto grid = output->wset()->get_workspace_grid_size();
for (int i = 0; i < grid.width; i++)
{
return;
for (int j = 0; j < grid.height; j++)
{
if (wall->get_workspace_rectangle({i, j}) & in_grid)
{
return wf::point_t{i, j};
}
}
}

int tmpx = x / og.width;
int tmpy = y / og.height;
if ((tmpx != target_ws.x) || (tmpy != target_ws.y))
return std::nullopt;
}

bool update_target_workspace(int x, int y)
{
auto tmp = find_workspace_at(x, y);
if (tmp.has_value() && (tmp != target_ws))
{
shade_workspace(target_ws, true);
target_ws = {tmpx, tmpy};
target_ws = tmp.value();
shade_workspace(target_ws, false);
return true;
}

return false;
}

wf::effect_hook_t pre_frame = [=] ()
Expand Down
5 changes: 4 additions & 1 deletion plugins/single_plugins/move.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,10 @@ class wayfire_move : public wf::per_output_plugin_instance_t,
wf::signal::connection_t<wf::view_move_request_signal> move_request =
[=] (wf::view_move_request_signal *ev)
{
initiate(ev->view, last_input_press_position);
if (!drag_helper->view)
{
initiate(ev->view, last_input_press_position);
}
};

/**
Expand Down
7 changes: 7 additions & 0 deletions plugins/tile/tree-controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ nonstd::observer_ptr<view_node_t> find_first_view_in_direction(
/* ------------------------ move_view_controller_t -------------------------- */
move_view_controller_t::move_view_controller_t(wf::workspace_set_t *set, wayfire_toplevel_view grabbed_view)
{
if (this->drag_helper->view)
{
// Race conditions are possible: spontaneous move requests from xwayland could trigger move without
// a pressed button, and then if the user tries to use simple-tile, it leads to a crash.
return;
}

this->drag_helper->set_pending_drag(wf::get_core().get_cursor_position());

move_drag::drag_options_t drag_options;
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 @@ -105,7 +105,7 @@ class plugin_interface_t
using wayfire_plugin_load_func = wf::plugin_interface_t * (*)();

/** The version of Wayfire's API/ABI */
constexpr uint32_t WAYFIRE_API_ABI_VERSION = 2024'04'15;
constexpr uint32_t WAYFIRE_API_ABI_VERSION = 2024'04'16;

/**
* Each plugin must also provide a function which returns the Wayfire API/ABI
Expand Down
17 changes: 17 additions & 0 deletions src/api/wayfire/signal-definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,23 @@ struct post_input_event_signal
wlr_input_device *device;
};

/**
* Emitted on core when the pointer focus changes.
*/
struct pointer_focus_changed_signal
{
wf::scene::node_ptr new_focus;
};

/**
* Emitted on core when the touch focus changes.
*/
struct touch_focus_changed_signal
{
wf::scene::node_ptr new_focus;
int32_t finger_id;
};

/**
* on: core
* when: When the config file is reloaded
Expand Down
4 changes: 4 additions & 0 deletions src/core/seat/pointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ void wf::pointer_t::update_cursor_focus(wf::scene::node_ptr new_focus)
// avoid the last cursor image getting stuck outside of its surface.
wf::get_core().set_cursor("default");
}

wf::pointer_focus_changed_signal ev;
ev.new_focus = new_focus;
wf::get_core().emit(&ev);
}

wf::scene::node_ptr wf::pointer_t::get_focus() const
Expand Down
3 changes: 3 additions & 0 deletions src/core/seat/seat-impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ struct seat_t::impl
std::weak_ptr<wf::view_interface_t> _last_active_view;
wf::signal::connection_t<scene::root_node_update_signal> on_root_node_updated;
void update_active_view(wf::scene::node_ptr new_focus);

// Last serial used for button press, release, touch down/up and or tablet tip events.
uint32_t last_press_release_serial = 0;
};
}

Expand Down
5 changes: 5 additions & 0 deletions src/core/seat/touch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ void wf::touch_interface_t::set_touch_focus(wf::scene::node_ptr node,
auto local = get_node_local_coords(node.get(), point);
node->touch_interaction().handle_touch_down(time, id, local);
}

wf::touch_focus_changed_signal ev;
ev.finger_id = id;
ev.new_focus = node;
wf::get_core().emit(&ev);
}

void wf::touch_interface_t::transfer_grab(scene::node_ptr grab_node)
Expand Down
13 changes: 11 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ static void wlr_log_handler(wlr_log_importance level,
wf::log::log_plain(wlevel, buffer);
}

static std::optional<int> exit_because_signal;
static void signal_handler(int signal)
{
std::string error;
Expand All @@ -124,12 +125,12 @@ static void signal_handler(int signal)
break;

case SIGINT:
LOGI("Got SIGINT, shutting down");
exit_because_signal = SIGINT;
wf::get_core().shutdown();
return;

case SIGTERM:
LOGI("Got SIGTERM, shutting down");
exit_because_signal = SIGTERM;
wf::get_core().shutdown();
return;

Expand Down Expand Up @@ -445,6 +446,14 @@ int main(int argc, char *argv[])
core.post_init();

wl_display_run(core.display);
if (exit_because_signal == SIGINT)
{
LOGI("Got SIGINT, shutting down");
} else if (exit_because_signal == SIGTERM)
{
LOGI("Got SIGTERM, shutting down");
}

wf::compositor_core_impl_t::deallocate_core();
LOGI("Shutdown successful!");
return EXIT_SUCCESS;
Expand Down
3 changes: 1 addition & 2 deletions src/view/wlr-surface-pointer-interaction.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include <wayfire/view.hpp>
#include <wayfire/scene.hpp>
#include "../core/seat/input-manager.hpp"
#include "../core/core-impl.hpp"
#include "core/seat/seat-impl.hpp"
#include "view-impl.hpp"
Expand Down Expand Up @@ -175,7 +174,7 @@ class wlr_surface_pointer_interaction_t final : public wf::pointer_interaction_t
{
auto& seat = wf::get_core_impl().seat;
bool drag_was_active = seat->priv->drag_active;
wlr_seat_pointer_notify_button(seat->seat,
seat->priv->last_press_release_serial = wlr_seat_pointer_notify_button(seat->seat,
event.time_msec, event.button, event.state);

if (drag_was_active != seat->priv->drag_active)
Expand Down
12 changes: 8 additions & 4 deletions src/view/wlr-surface-touch-interaction.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <wayfire/scene.hpp>
#include "../core/seat/input-manager.hpp"
#include "../core/core-impl.hpp"
#include "../core/seat/seat-impl.hpp"
#include "view-impl.hpp"
#include "wayfire/unstable/wlr-surface-node.hpp"
#include "wayfire/geometry.hpp"
Expand All @@ -21,7 +21,8 @@ class wlr_surface_touch_interaction_t final : public wf::touch_interaction_t
wf::pointf_t local) override
{
auto& seat = wf::get_core_impl().seat;
wlr_seat_touch_notify_down(seat->seat, surface, time_ms, finger_id, local.x, local.y);
seat->priv->last_press_release_serial =
wlr_seat_touch_notify_down(seat->seat, surface, time_ms, finger_id, local.x, local.y);

if (!seat->priv->drag_active)
{
Expand All @@ -31,8 +32,11 @@ class wlr_surface_touch_interaction_t final : public wf::touch_interaction_t

void handle_touch_up(uint32_t time_ms, int finger_id, wf::pointf_t) override
{
auto seat = wf::get_core().get_current_seat();
wlr_seat_touch_notify_up(seat, time_ms, finger_id);
auto& seat = wf::get_core_impl().seat;
wlr_seat_touch_notify_up(seat->seat, time_ms, finger_id);
// FIXME: wlroots does not give us the serial for touch up yet, so we just reset it to something
// invalid.
seat->priv->last_press_release_serial = 0;
}

void handle_touch_motion(uint32_t time_ms, int finger_id,
Expand Down
17 changes: 13 additions & 4 deletions src/view/xdg-shell/xdg-toplevel-view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <wayfire/window-manager.hpp>
#include <wayfire/view-helpers.hpp>
#include <wayfire/unstable/wlr-view-events.hpp>
#include "../core/seat/seat-impl.hpp"


// --------------------------------------- xdg-toplevel-base impl --------------------------------------------
Expand Down Expand Up @@ -200,14 +201,22 @@ wf::xdg_toplevel_view_t::xdg_toplevel_view_t(wlr_xdg_toplevel *tlvl) : xdg_tople
set_toplevel_parent(toplevel_cast(parent));
});

on_request_move.set_callback([&] (void*)
on_request_move.set_callback([&] (void *data)
{
wf::get_core().default_wm->move_request({this});
auto ev = static_cast<wlr_xdg_toplevel_move_event*>(data);
if (ev->serial == wf::get_core().seat->priv->last_press_release_serial)
{
wf::get_core().default_wm->move_request({this});
return;
}
});
on_request_resize.set_callback([&] (auto data)
{
auto ev = static_cast<wlr_xdg_toplevel_resize_event*>(data);
wf::get_core().default_wm->resize_request({this}, ev->edges);
if (ev->serial == wf::get_core().seat->priv->last_press_release_serial)
{
wf::get_core().default_wm->resize_request({this}, ev->edges);
}
});
on_request_minimize.set_callback([&] (void*)
{
Expand Down Expand Up @@ -301,7 +310,7 @@ void wf::xdg_toplevel_view_t::map()
this->set_output(wf::get_core().seat->get_active_output());
}

if (!parent)
if (!parent && get_output())
{
wf::scene::readd_front(get_output()->wset()->get_node(), get_root_node());
get_output()->wset()->add_view({this});
Expand Down
6 changes: 3 additions & 3 deletions src/view/xwayland/xwayland-toplevel-view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ class wayfire_xwayland_view : public wf::toplevel_view_interface_t, public wayfi
this->set_output(wf::get_core().seat->get_active_output());
}

if (!parent)
if (!parent && get_output())
{
wf::scene::readd_front(get_output()->wset()->get_node(), get_root_node());
get_output()->wset()->add_view({this});
Expand Down Expand Up @@ -459,12 +459,12 @@ class wayfire_xwayland_view : public wf::toplevel_view_interface_t, public wayfi
void handle_toplevel_state_changed(wf::toplevel_state_t old_state)
{
surface_root_node->set_offset(wf::origin(toplevel->calculate_base_geometry()));
if (xw && !old_state.mapped && toplevel->current().mapped)
if (xw && xw->surface && !old_state.mapped && toplevel->current().mapped)
{
map(xw->surface);
}

if (old_state.mapped && !toplevel->current().mapped)
if (is_mapped() && old_state.mapped && !toplevel->current().mapped)
{
unmap();
}
Expand Down
Loading