summaryrefslogtreecommitdiff
path: root/Servers/WindowServer
diff options
context:
space:
mode:
Diffstat (limited to 'Servers/WindowServer')
-rw-r--r--Servers/WindowServer/WSAPITypes.h1
-rw-r--r--Servers/WindowServer/WSClientConnection.cpp9
-rw-r--r--Servers/WindowServer/WSEvent.h5
-rw-r--r--Servers/WindowServer/WSEventLoop.cpp2
-rw-r--r--Servers/WindowServer/WSWindow.cpp3
-rw-r--r--Servers/WindowServer/WSWindow.h7
-rw-r--r--Servers/WindowServer/WSWindowFrame.cpp2
-rw-r--r--Servers/WindowServer/WSWindowManager.cpp30
-rw-r--r--Servers/WindowServer/WSWindowManager.h3
9 files changed, 49 insertions, 13 deletions
diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h
index 2f54a0beaa..071c138e81 100644
--- a/Servers/WindowServer/WSAPITypes.h
+++ b/Servers/WindowServer/WSAPITypes.h
@@ -264,6 +264,7 @@ struct WSAPI_ClientMessage {
bool has_alpha_channel;
bool modal;
bool resizable;
+ bool fullscreen;
WSAPI_WindowType type;
float opacity;
WSAPI_Size base_size;
diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp
index 81ba62134d..6f3a3da9aa 100644
--- a/Servers/WindowServer/WSClientConnection.cpp
+++ b/Servers/WindowServer/WSClientConnection.cpp
@@ -413,6 +413,10 @@ void WSClientConnection::handle_request(const WSAPISetWindowRectRequest& request
return;
}
auto& window = *(*it).value;
+ if (window.is_fullscreen()) {
+ dbgprintf("WSClientConnection: Ignoring SetWindowRect request for fullscreen window\n");
+ return;
+ }
window.set_rect(request.rect());
window.request_update(request.rect());
}
@@ -474,11 +478,12 @@ void WSClientConnection::handle_request(const WSAPIGetClipboardContentsRequest&)
void WSClientConnection::handle_request(const WSAPICreateWindowRequest& request)
{
int window_id = m_next_window_id++;
- auto window = make<WSWindow>(*this, request.window_type(), window_id, request.is_modal(), request.is_resizable());
+ auto window = make<WSWindow>(*this, request.window_type(), window_id, request.is_modal(), request.is_resizable(), request.is_fullscreen());
window->set_background_color(request.background_color());
window->set_has_alpha_channel(request.has_alpha_channel());
window->set_title(request.title());
- window->set_rect(request.rect());
+ if (!request.is_fullscreen())
+ window->set_rect(request.rect());
window->set_opacity(request.opacity());
window->set_size_increment(request.size_increment());
window->set_base_size(request.base_size());
diff --git a/Servers/WindowServer/WSEvent.h b/Servers/WindowServer/WSEvent.h
index 72cd89c2f0..8f8fe983bc 100644
--- a/Servers/WindowServer/WSEvent.h
+++ b/Servers/WindowServer/WSEvent.h
@@ -581,7 +581,7 @@ private:
class WSAPICreateWindowRequest : public WSAPIClientRequest {
public:
- WSAPICreateWindowRequest(int client_id, const Rect& rect, const String& title, bool has_alpha_channel, bool modal, bool resizable, float opacity, const Size& base_size, const Size& size_increment, WSWindowType window_type, Color background_color)
+ WSAPICreateWindowRequest(int client_id, const Rect& rect, const String& title, bool has_alpha_channel, bool modal, bool resizable, bool fullscreen, float opacity, const Size& base_size, const Size& size_increment, WSWindowType window_type, Color background_color)
: WSAPIClientRequest(WSEvent::APICreateWindowRequest, client_id)
, m_rect(rect)
, m_title(title)
@@ -589,6 +589,7 @@ public:
, m_has_alpha_channel(has_alpha_channel)
, m_modal(modal)
, m_resizable(resizable)
+ , m_fullscreen(fullscreen)
, m_size_increment(size_increment)
, m_base_size(base_size)
, m_window_type(window_type)
@@ -601,6 +602,7 @@ public:
bool has_alpha_channel() const { return m_has_alpha_channel; }
bool is_modal() const { return m_modal; }
bool is_resizable() const { return m_resizable; }
+ bool is_fullscreen() const { return m_fullscreen; }
float opacity() const { return m_opacity; }
Size size_increment() const { return m_size_increment; }
Size base_size() const { return m_base_size; }
@@ -614,6 +616,7 @@ private:
bool m_has_alpha_channel { false };
bool m_modal { false };
bool m_resizable { false };
+ bool m_fullscreen { false };
Size m_size_increment;
Size m_base_size;
WSWindowType m_window_type;
diff --git a/Servers/WindowServer/WSEventLoop.cpp b/Servers/WindowServer/WSEventLoop.cpp
index e32ec7343f..904dfca2fc 100644
--- a/Servers/WindowServer/WSEventLoop.cpp
+++ b/Servers/WindowServer/WSEventLoop.cpp
@@ -185,7 +185,7 @@ bool WSEventLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessag
break;
case WSAPI_ClientMessage::Type::CreateWindow:
ASSERT(message.text_length < (ssize_t)sizeof(message.text));
- post_event(client, make<WSAPICreateWindowRequest>(client_id, message.window.rect, String(message.text, message.text_length), message.window.has_alpha_channel, message.window.modal, message.window.resizable, message.window.opacity, message.window.base_size, message.window.size_increment, from_api(message.window.type), Color::from_rgba(message.window.background_color)));
+ post_event(client, make<WSAPICreateWindowRequest>(client_id, message.window.rect, String(message.text, message.text_length), message.window.has_alpha_channel, message.window.modal, message.window.resizable, message.window.fullscreen, message.window.opacity, message.window.base_size, message.window.size_increment, from_api(message.window.type), Color::from_rgba(message.window.background_color)));
break;
case WSAPI_ClientMessage::Type::DestroyWindow:
post_event(client, make<WSAPIDestroyWindowRequest>(client_id, message.window_id));
diff --git a/Servers/WindowServer/WSWindow.cpp b/Servers/WindowServer/WSWindow.cpp
index 88561122c8..a6a85ff79b 100644
--- a/Servers/WindowServer/WSWindow.cpp
+++ b/Servers/WindowServer/WSWindow.cpp
@@ -28,11 +28,12 @@ WSWindow::WSWindow(CObject& internal_owner, WSWindowType type)
WSWindowManager::the().add_window(*this);
}
-WSWindow::WSWindow(WSClientConnection& client, WSWindowType window_type, int window_id, bool modal, bool resizable)
+WSWindow::WSWindow(WSClientConnection& client, WSWindowType window_type, int window_id, bool modal, bool resizable, bool fullscreen)
: m_client(&client)
, m_type(window_type)
, m_modal(modal)
, m_resizable(resizable)
+ , m_fullscreen(fullscreen)
, m_window_id(window_id)
, m_icon(default_window_icon())
, m_icon_path(default_window_icon_path())
diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h
index 5c9fad376b..7ef0e27608 100644
--- a/Servers/WindowServer/WSWindow.h
+++ b/Servers/WindowServer/WSWindow.h
@@ -16,7 +16,7 @@ class WSMouseEvent;
class WSWindow final : public CObject, public InlineLinkedListNode<WSWindow> {
public:
- WSWindow(WSClientConnection&, WSWindowType, int window_id, bool modal, bool resizable);
+ WSWindow(WSClientConnection&, WSWindowType, int window_id, bool modal, bool resizable, bool fullscreen);
WSWindow(CObject&, WSWindowType);
virtual ~WSWindow() override;
@@ -32,6 +32,8 @@ public:
bool is_maximized() const { return m_maximized; }
void set_maximized(bool);
+ bool is_fullscreen() const { return m_fullscreen; }
+
WSWindowFrame& frame() { return m_frame; }
const WSWindowFrame& frame() const { return m_frame; }
@@ -63,7 +65,7 @@ public:
bool is_modal() const { return m_modal; }
- bool is_resizable() const { return m_resizable; }
+ bool is_resizable() const { return m_resizable && !m_fullscreen; }
Rect rect() const { return m_rect; }
void set_rect(const Rect&);
@@ -155,6 +157,7 @@ private:
bool m_listens_to_wm_events { false };
bool m_minimized { false };
bool m_maximized { false };
+ bool m_fullscreen { false };
RetainPtr<GraphicsBitmap> m_backing_store;
RetainPtr<GraphicsBitmap> m_last_backing_store;
int m_window_id { -1 };
diff --git a/Servers/WindowServer/WSWindowFrame.cpp b/Servers/WindowServer/WSWindowFrame.cpp
index 14e58319d9..ebe9ef3aef 100644
--- a/Servers/WindowServer/WSWindowFrame.cpp
+++ b/Servers/WindowServer/WSWindowFrame.cpp
@@ -254,6 +254,8 @@ void WSWindowFrame::notify_window_rect_changed(const Rect& old_rect, const Rect&
void WSWindowFrame::on_mouse_event(const WSMouseEvent& event)
{
+ ASSERT(!m_window.is_fullscreen());
+
auto& wm = WSWindowManager::the();
if (m_window.type() != WSWindowType::Normal)
return;
diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp
index 1dc166d217..d3e893c43d 100644
--- a/Servers/WindowServer/WSWindowManager.cpp
+++ b/Servers/WindowServer/WSWindowManager.cpp
@@ -311,6 +311,12 @@ void WSWindowManager::add_window(WSWindow& window)
{
m_windows.set(&window);
m_windows_in_order.append(&window);
+
+ if (window.is_fullscreen()) {
+ WSEventLoop::the().post_event(window, make<WSResizeEvent>(window.rect(), m_screen_rect));
+ window.set_rect(m_screen_rect);
+ }
+
set_active_window(&window);
if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher)
m_switcher.refresh();
@@ -792,7 +798,7 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
// First check if we should initiate a drag or resize (Logo+LMB or Logo+RMB).
// In those cases, the event is swallowed by the window manager.
if (window.type() == WSWindowType::Normal) {
- if (m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left) {
+ if (!window.is_fullscreen() && m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left) {
hovered_window = &window;
start_window_drag(window, event);
return IterationDecision::Abort;
@@ -913,7 +919,7 @@ void WSWindowManager::compose()
m_back_painter->blit(dirty_rect.location(), *m_wallpaper, dirty_rect);
}
- for_each_visible_window_from_back_to_front([&] (WSWindow& window) {
+ auto compose_window = [&] (WSWindow& window) -> IterationDecision {
if (!any_dirty_rect_intersects_window(window))
return IterationDecision::Continue;
PainterStateSaver saver(*m_back_painter);
@@ -926,7 +932,8 @@ void WSWindowManager::compose()
m_back_painter->add_clip_rect(dirty_rect);
if (!backing_store)
m_back_painter->fill_rect(dirty_rect, window.background_color());
- window.frame().paint(*m_back_painter);
+ if (!window.is_fullscreen())
+ window.frame().paint(*m_back_painter);
if (!backing_store)
continue;
Rect dirty_rect_in_window_coordinates = Rect::intersection(dirty_rect, window.rect());
@@ -949,10 +956,19 @@ void WSWindowManager::compose()
}
}
return IterationDecision::Continue;
- });
+ };
+
+ if (auto* fullscreen_window = active_fullscreen_window()) {
+ compose_window(*fullscreen_window);
+ } else {
+ for_each_visible_window_from_back_to_front([&] (WSWindow& window) {
+ return compose_window(window);
+ });
+
+ draw_geometry_label();
+ draw_menubar();
+ }
- draw_geometry_label();
- draw_menubar();
draw_cursor();
if (m_flash_flush) {
@@ -977,6 +993,8 @@ void WSWindowManager::invalidate_cursor()
Rect WSWindowManager::menubar_rect() const
{
+ if (active_fullscreen_window())
+ return { };
return { 0, 0, m_screen_rect.width(), 18 };
}
diff --git a/Servers/WindowServer/WSWindowManager.h b/Servers/WindowServer/WSWindowManager.h
index 4c11c5e95f..cddb2fe714 100644
--- a/Servers/WindowServer/WSWindowManager.h
+++ b/Servers/WindowServer/WSWindowManager.h
@@ -122,6 +122,9 @@ public:
void start_window_resize(WSWindow&, const Point&, MouseButton);
void start_window_resize(WSWindow&, const WSMouseEvent&);
+ const WSWindow* active_fullscreen_window() const { return (m_active_window && m_active_window->is_fullscreen()) ? m_active_window : nullptr; }
+ WSWindow* active_fullscreen_window() { return (m_active_window && m_active_window->is_fullscreen()) ? m_active_window : nullptr; }
+
private:
void process_mouse_event(WSMouseEvent&, WSWindow*& hovered_window);
void deliver_mouse_event(WSWindow& window, WSMouseEvent& event);