1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:27:35 +00:00

LibGUI+WindowServer: Add a GResizeCorner widget.

This widget is automatically included in GStatusBar, but can be added in
any other place, too. When clicked (with the left button), it initiates a
window resize (using a WM request.)

In this patch I also fixed up some issues with override cursors being
cleared after the WindowServer finishes a drag or resize.
This commit is contained in:
Andreas Kling 2019-05-03 01:38:24 +02:00
parent 34c5db61aa
commit ea9a39a9f2
19 changed files with 189 additions and 26 deletions

View file

@ -24,6 +24,7 @@
//#define COALESCING_DEBUG
int GEventLoop::s_event_fd = -1;
int GEventLoop::s_my_client_id = -1;
pid_t GEventLoop::s_server_pid = -1;
void GEventLoop::connect_to_server()
@ -59,8 +60,7 @@ void GEventLoop::connect_to_server()
request.type = WSAPI_ClientMessage::Type::Greeting;
request.greeting.client_pid = getpid();
auto response = sync_request(request, WSAPI_ServerMessage::Type::Greeting);
s_server_pid = response.greeting.server_pid;
GDesktop::the().did_receive_screen_rect(Badge<GEventLoop>(), response.greeting.screen_rect);
handle_greeting(response);
}
GEventLoop::GEventLoop()
@ -235,8 +235,7 @@ void GEventLoop::process_unprocessed_bundles()
for (auto& bundle : unprocessed_bundles) {
auto& event = bundle.message;
if (event.type == WSAPI_ServerMessage::Type::Greeting) {
s_server_pid = event.greeting.server_pid;
GDesktop::the().did_receive_screen_rect(Badge<GEventLoop>(), event.greeting.screen_rect);
handle_greeting(event);
continue;
}
@ -402,3 +401,10 @@ WSAPI_ServerMessage GEventLoop::sync_request(const WSAPI_ClientMessage& request,
ASSERT(success);
return response;
}
void GEventLoop::handle_greeting(WSAPI_ServerMessage& message)
{
s_server_pid = message.greeting.server_pid;
s_my_client_id = message.greeting.your_client_id;
GDesktop::the().did_receive_screen_rect(Badge<GEventLoop>(), message.greeting.screen_rect);
}

View file

@ -21,6 +21,7 @@ public:
WSAPI_ServerMessage sync_request(const WSAPI_ClientMessage& request, WSAPI_ServerMessage::Type response_type);
static pid_t server_pid() { return s_server_pid; }
static int my_client_id() { return s_my_client_id; }
virtual void take_pending_events_from(CEventLoop& other) override
{
@ -59,6 +60,7 @@ private:
void handle_menu_event(const WSAPI_ServerMessage&);
void handle_window_entered_or_left_event(const WSAPI_ServerMessage&, GWindow&);
void handle_wm_event(const WSAPI_ServerMessage&, GWindow&);
void handle_greeting(WSAPI_ServerMessage&);
void connect_to_server();
struct IncomingWSMessageBundle {
@ -68,5 +70,6 @@ private:
Vector<IncomingWSMessageBundle, 64> m_unprocessed_bundles;
static pid_t s_server_pid;
static pid_t s_event_fd;
static int s_my_client_id;
static int s_event_fd;
};

46
LibGUI/GResizeCorner.cpp Normal file
View file

@ -0,0 +1,46 @@
#include <LibGUI/GResizeCorner.h>
#include <LibGUI/GPainter.h>
#include <LibGUI/GWindow.h>
#include <SharedGraphics/GraphicsBitmap.h>
#include <WindowServer/WSAPITypes.h>
GResizeCorner::GResizeCorner(GWidget* parent)
: GWidget(parent)
{
set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
set_preferred_size({ 16, 16 });
m_bitmap = GraphicsBitmap::load_from_file("/res/icons/resize-corner.png");
ASSERT(m_bitmap);
}
GResizeCorner::~GResizeCorner()
{
}
void GResizeCorner::paint_event(GPaintEvent& event)
{
GPainter painter(*this);
painter.add_clip_rect(event.rect());
painter.fill_rect(rect(), background_color());
painter.blit({ 0, 0 }, *m_bitmap, m_bitmap->rect());
GWidget::paint_event(event);
}
void GResizeCorner::mousedown_event(GMouseEvent& event)
{
if (event.button() == GMouseButton::Left)
window()->start_wm_resize();
GWidget::mousedown_event(event);
}
void GResizeCorner::enter_event(CEvent& event)
{
window()->set_override_cursor(GStandardCursor::ResizeDiagonalTLBR);
GWidget::enter_event(event);
}
void GResizeCorner::leave_event(CEvent& event)
{
window()->set_override_cursor(GStandardCursor::None);
GWidget::leave_event(event);
}

18
LibGUI/GResizeCorner.h Normal file
View file

@ -0,0 +1,18 @@
#include <LibGUI/GWidget.h>
class GResizeCorner : public GWidget {
public:
explicit GResizeCorner(GWidget* parent);
virtual ~GResizeCorner() override;
virtual const char* class_name() const override { return "GResizeCorner"; }
protected:
virtual void paint_event(GPaintEvent&) override;
virtual void mousedown_event(GMouseEvent&) override;
virtual void enter_event(CEvent&) override;
virtual void leave_event(CEvent&) override;
private:
RetainPtr<GraphicsBitmap> m_bitmap;
};

View file

@ -3,6 +3,7 @@
#include <LibGUI/GBoxLayout.h>
#include <SharedGraphics/StylePainter.h>
#include <LibGUI/GPainter.h>
#include <LibGUI/GResizeCorner.h>
GStatusBar::GStatusBar(GWidget* parent)
: GWidget(parent)
@ -17,6 +18,8 @@ GStatusBar::GStatusBar(GWidget* parent)
m_label->set_frame_shape(FrameShape::Panel);
m_label->set_frame_thickness(1);
m_label->set_text_alignment(TextAlignment::CenterLeft);
m_corner = new GResizeCorner(this);
}
GStatusBar::~GStatusBar()

View file

@ -3,6 +3,7 @@
#include <LibGUI/GWidget.h>
class GLabel;
class GResizeCorner;
class GStatusBar : public GWidget {
public:
@ -18,4 +19,5 @@ private:
virtual void paint_event(GPaintEvent&) override;
GLabel* m_label { nullptr };
GResizeCorner* m_corner { nullptr };
};

View file

@ -490,3 +490,12 @@ void GWindow::set_icon_path(const String& path)
message.text_length = path.length();
GEventLoop::post_message_to_server(message);
}
void GWindow::start_wm_resize()
{
WSAPI_ClientMessage message;
message.type = WSAPI_ClientMessage::Type::WM_StartWindowResize;
message.wm.client_id = GEventLoop::my_client_id();
message.wm.window_id = m_window_id;
GEventLoop::post_message_to_server(message);
}

View file

@ -16,6 +16,8 @@ enum class GStandardCursor {
IBeam,
ResizeHorizontal,
ResizeVertical,
ResizeDiagonalTLBR,
ResizeDiagonalBLTR,
};
class GWindow : public CObject {
@ -71,6 +73,8 @@ public:
void hide();
void close();
void start_wm_resize();
GWidget* main_widget() { return m_main_widget; }
const GWidget* main_widget() const { return m_main_widget; }
void set_main_widget(GWidget*);

View file

@ -53,6 +53,7 @@ LIBGUI_OBJS = \
GSpinBox.o \
GGroupBox.o \
GSlider.o \
GResizeCorner.o \
GWindow.o
OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)