diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-02-21 00:21:23 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-02-21 00:21:23 +0100 |
commit | 6084cd0c56f9d1949b8bb07db5729d2a0108d5a4 (patch) | |
tree | 63aa1fb2ff50cc5c132c6be67b671e316ca05bf2 | |
parent | fd575055c2215ce2ce42efaa82be53a94c7b3932 (diff) | |
download | serenity-6084cd0c56f9d1949b8bb07db5729d2a0108d5a4.zip |
Add concept of size increments to windowing system.
Use this to implement incremental resizing for Terminal so that we only
ever resize to fit a perfect number of rows and columns.
This is very nice. :^)
-rw-r--r-- | Applications/Terminal/Terminal.cpp | 7 | ||||
-rw-r--r-- | Applications/Terminal/Terminal.h | 2 | ||||
-rw-r--r-- | Applications/Terminal/main.cpp | 1 | ||||
-rw-r--r-- | LibGUI/GWindow.cpp | 2 | ||||
-rw-r--r-- | LibGUI/GWindow.h | 7 | ||||
-rw-r--r-- | SharedGraphics/Size.h | 3 | ||||
-rw-r--r-- | WindowServer/WSAPITypes.h | 2 | ||||
-rw-r--r-- | WindowServer/WSClientConnection.cpp | 1 | ||||
-rw-r--r-- | WindowServer/WSMessage.h | 8 | ||||
-rw-r--r-- | WindowServer/WSMessageLoop.cpp | 2 | ||||
-rw-r--r-- | WindowServer/WSWindow.h | 8 | ||||
-rw-r--r-- | WindowServer/WSWindowManager.cpp | 8 |
12 files changed, 47 insertions, 4 deletions
diff --git a/Applications/Terminal/Terminal.cpp b/Applications/Terminal/Terminal.cpp index 9407fdba06..76b753af35 100644 --- a/Applications/Terminal/Terminal.cpp +++ b/Applications/Terminal/Terminal.cpp @@ -785,7 +785,6 @@ void Terminal::force_repaint() { for (int i = 0; i < m_rows; ++i) line(i).dirty = true; - m_need_full_flush = true; update(); } @@ -795,3 +794,9 @@ void Terminal::resize_event(GResizeEvent& event) int new_rows = event.size().height() / m_line_height; set_size(new_columns, new_rows); } + +void Terminal::apply_size_increments_to_window(GWindow& window) +{ + window.set_size_increment({ font().glyph_width(), m_line_height }); + window.set_base_size({ m_inset, m_inset }); +} diff --git a/Applications/Terminal/Terminal.h b/Applications/Terminal/Terminal.h index e2b622cd20..67e453bc5a 100644 --- a/Applications/Terminal/Terminal.h +++ b/Applications/Terminal/Terminal.h @@ -21,6 +21,8 @@ public: void flush_dirty_lines(); void force_repaint(); + void apply_size_increments_to_window(GWindow&); + private: virtual void event(GEvent&) override; virtual void paint_event(GPaintEvent&) override; diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp index a63970a7ee..94ec08829c 100644 --- a/Applications/Terminal/main.cpp +++ b/Applications/Terminal/main.cpp @@ -92,6 +92,7 @@ int main(int argc, char** argv) window->set_has_alpha_channel(true); window->set_main_widget(&terminal); window->move_to(300, 300); + terminal.apply_size_increments_to_window(*window); window->show(); auto menubar = make<GMenuBar>(); diff --git a/LibGUI/GWindow.cpp b/LibGUI/GWindow.cpp index f7b9bf000e..75bfc71ccb 100644 --- a/LibGUI/GWindow.cpp +++ b/LibGUI/GWindow.cpp @@ -61,6 +61,8 @@ void GWindow::show() request.window.rect = m_rect_when_windowless; request.window.has_alpha_channel = m_has_alpha_channel; request.window.opacity = m_opacity_when_windowless; + request.window.size_increment = m_size_increment; + request.window.base_size = m_base_size; ASSERT(m_title_when_windowless.length() < sizeof(request.text)); strcpy(request.text, m_title_when_windowless.characters()); request.text_length = m_title_when_windowless.length(); diff --git a/LibGUI/GWindow.h b/LibGUI/GWindow.h index c40387cf7c..21328d224c 100644 --- a/LibGUI/GWindow.h +++ b/LibGUI/GWindow.h @@ -70,6 +70,11 @@ public: GraphicsBitmap* backing() { return m_backing.ptr(); } + Size size_increment() const { return m_size_increment; } + void set_size_increment(const Size& increment) { m_size_increment = increment; } + Size base_size() const { return m_base_size; } + void set_base_size(const Size& size) { m_base_size = size; } + private: virtual const char* class_name() const override { return "GWindow"; } @@ -83,6 +88,8 @@ private: Rect m_rect_when_windowless; String m_title_when_windowless; Vector<Rect> m_pending_paint_event_rects; + Size m_size_increment; + Size m_base_size; bool m_is_active { false }; bool m_should_exit_app_on_close { false }; bool m_has_alpha_channel { false }; diff --git a/SharedGraphics/Size.h b/SharedGraphics/Size.h index d5d914af19..62cf8b1c4b 100644 --- a/SharedGraphics/Size.h +++ b/SharedGraphics/Size.h @@ -10,7 +10,8 @@ public: Size(int w, int h) : m_width(w), m_height(h) { } Size(const WSAPI_Size&); - bool is_empty() const { return !m_width || !m_height; } + bool is_null() const { return !m_width && !m_height; } + bool is_empty() const { return m_width <= 0 || m_height <= 0; } int width() const { return m_width; } int height() const { return m_height; } diff --git a/WindowServer/WSAPITypes.h b/WindowServer/WSAPITypes.h index da39a9a04e..9cd0fea2d8 100644 --- a/WindowServer/WSAPITypes.h +++ b/WindowServer/WSAPITypes.h @@ -170,6 +170,8 @@ struct WSAPI_ClientMessage { WSAPI_Rect rect; bool has_alpha_channel; float opacity; + WSAPI_Size base_size; + WSAPI_Size size_increment; } window; struct { WSAPI_Size size; diff --git a/WindowServer/WSClientConnection.cpp b/WindowServer/WSClientConnection.cpp index 2a171a8056..b3c1271424 100644 --- a/WindowServer/WSClientConnection.cpp +++ b/WindowServer/WSClientConnection.cpp @@ -319,6 +319,7 @@ void WSClientConnection::handle_request(WSAPICreateWindowRequest& request) window->set_title(request.title()); window->set_rect(request.rect()); window->set_opacity(request.opacity()); + window->set_size_increment(request.size_increment()); m_windows.set(window_id, move(window)); WSAPI_ServerMessage response; response.type = WSAPI_ServerMessage::Type::DidCreateWindow; diff --git a/WindowServer/WSMessage.h b/WindowServer/WSMessage.h index b87b0339cb..cf7a8bc319 100644 --- a/WindowServer/WSMessage.h +++ b/WindowServer/WSMessage.h @@ -349,12 +349,14 @@ private: class WSAPICreateWindowRequest : public WSAPIClientRequest { public: - WSAPICreateWindowRequest(int client_id, const Rect& rect, const String& title, bool has_alpha_channel, float opacity) + WSAPICreateWindowRequest(int client_id, const Rect& rect, const String& title, bool has_alpha_channel, float opacity, const Size& base_size, const Size& size_increment) : WSAPIClientRequest(WSMessage::APICreateWindowRequest, client_id) , m_rect(rect) , m_title(title) , m_opacity(opacity) , m_has_alpha_channel(has_alpha_channel) + , m_base_size(base_size) + , m_size_increment(size_increment) { } @@ -362,12 +364,16 @@ public: String title() const { return m_title; } bool has_alpha_channel() const { return m_has_alpha_channel; } float opacity() const { return m_opacity; } + Size size_increment() const { return m_size_increment; } + Size base_size() const { return m_base_size; } private: Rect m_rect; String m_title; float m_opacity { 0 }; bool m_has_alpha_channel { false }; + Size m_size_increment; + Size m_base_size; }; class WSAPIDestroyWindowRequest : public WSAPIClientRequest { diff --git a/WindowServer/WSMessageLoop.cpp b/WindowServer/WSMessageLoop.cpp index bbdec4fe35..15ea696fc6 100644 --- a/WindowServer/WSMessageLoop.cpp +++ b/WindowServer/WSMessageLoop.cpp @@ -302,7 +302,7 @@ void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMess break; case WSAPI_ClientMessage::Type::CreateWindow: ASSERT(message.text_length < sizeof(message.text)); - post_message(client, make<WSAPICreateWindowRequest>(client_id, message.window.rect, String(message.text, message.text_length), message.window.has_alpha_channel, message.window.opacity)); + post_message(client, make<WSAPICreateWindowRequest>(client_id, message.window.rect, String(message.text, message.text_length), message.window.has_alpha_channel, message.window.opacity, message.window.base_size, message.window.size_increment)); break; case WSAPI_ClientMessage::Type::DestroyWindow: post_message(client, make<WSAPIDestroyWindowRequest>(client_id, message.window_id)); diff --git a/WindowServer/WSWindow.h b/WindowServer/WSWindow.h index f4d6c28b5d..15745a55a0 100644 --- a/WindowServer/WSWindow.h +++ b/WindowServer/WSWindow.h @@ -70,6 +70,12 @@ public: bool has_painted_since_last_resize() const { return m_has_painted_since_last_resize; } void set_has_painted_since_last_resize(bool b) { m_has_painted_since_last_resize = b; } + Size size_increment() const { return m_size_increment; } + void set_size_increment(const Size& increment) { m_size_increment = increment; } + + Size base_size() const { return m_base_size; } + void set_base_size(const Size& size) { m_base_size = size; } + // For InlineLinkedList. // FIXME: Maybe make a ListHashSet and then WSWindowManager can just use that. WSWindow* m_next { nullptr }; @@ -89,4 +95,6 @@ private: int m_window_id { -1 }; float m_opacity { 1 }; Rect m_last_lazy_resize_rect; + Size m_size_increment; + Size m_base_size; }; diff --git a/WindowServer/WSWindowManager.cpp b/WindowServer/WSWindowManager.cpp index 6f30461a28..1b7640cb69 100644 --- a/WindowServer/WSWindowManager.cpp +++ b/WindowServer/WSWindowManager.cpp @@ -548,6 +548,14 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& event_ auto new_rect = m_resize_window_original_rect; new_rect.set_width(max(50, new_rect.width() + dx)); new_rect.set_height(max(50, new_rect.height() + dy)); + + if (!m_resize_window->size_increment().is_null()) { + int horizontal_incs = (new_rect.width() - m_resize_window->base_size().width()) / m_resize_window->size_increment().width(); + new_rect.set_width(m_resize_window->base_size().width() + horizontal_incs * m_resize_window->size_increment().width()); + int vertical_incs = (new_rect.height() - m_resize_window->base_size().height()) / m_resize_window->size_increment().height(); + new_rect.set_height(m_resize_window->base_size().height() + vertical_incs * m_resize_window->size_increment().height()); + } + if (m_resize_window->rect() == new_rect) return; #ifdef RESIZE_DEBUG |