diff --git a/Applications/Terminal/Terminal.cpp b/Applications/Terminal/Terminal.cpp index 6b82ec8f8c7..12752d43b04 100644 --- a/Applications/Terminal/Terminal.cpp +++ b/Applications/Terminal/Terminal.cpp @@ -891,6 +891,7 @@ void Terminal::set_opacity(float opacity) { if (m_opacity == opacity) return; + window()->set_has_alpha_channel(opacity < 1); m_opacity = opacity; force_repaint(); } diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp index e7662718b61..3afb370a89b 100644 --- a/Applications/Terminal/main.cpp +++ b/Applications/Terminal/main.cpp @@ -116,7 +116,7 @@ int main(int argc, char** argv) }; slider->set_range(0, 100); - slider->set_value(80); + slider->set_value(100); auto menubar = make(); diff --git a/LibGUI/GEventLoop.cpp b/LibGUI/GEventLoop.cpp index ae41ad7da1f..34e06ea0c75 100644 --- a/LibGUI/GEventLoop.cpp +++ b/LibGUI/GEventLoop.cpp @@ -376,6 +376,9 @@ bool GEventLoop::wait_for_specific_event(WSAPI_ServerMessage::Type type, WSAPI_S FD_ZERO(&rfds); FD_SET(s_event_fd, &rfds); int rc = select(s_event_fd + 1, &rfds, nullptr, nullptr, nullptr); + if (rc < 0) { + perror("select"); + } ASSERT(rc > 0); ASSERT(FD_ISSET(s_event_fd, &rfds)); bool success = drain_messages_from_server(); diff --git a/LibGUI/GWindow.cpp b/LibGUI/GWindow.cpp index c1384ebe976..1dff4f2f746 100644 --- a/LibGUI/GWindow.cpp +++ b/LibGUI/GWindow.cpp @@ -386,8 +386,23 @@ void GWindow::set_automatic_cursor_tracking_widget(GWidget* widget) void GWindow::set_has_alpha_channel(bool value) { - ASSERT(!m_window_id); + if (m_has_alpha_channel == value) + return; m_has_alpha_channel = value; + if (!m_window_id) + return; + + m_pending_paint_event_rects.clear(); + m_back_bitmap = nullptr; + m_front_bitmap = nullptr; + + WSAPI_ClientMessage message; + message.type = WSAPI_ClientMessage::Type::SetWindowHasAlphaChannel; + message.window_id = m_window_id; + message.value = value; + GEventLoop::current().sync_request(message, WSAPI_ServerMessage::DidSetWindowHasAlphaChannel); + + update(); } void GWindow::set_double_buffering_enabled(bool value) diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h index be8027c98e4..e5f3be767a2 100644 --- a/Servers/WindowServer/WSAPITypes.h +++ b/Servers/WindowServer/WSAPITypes.h @@ -103,6 +103,7 @@ struct WSAPI_ServerMessage { DidSetWindowBackingStore, DidSetWallpaper, DidGetWallpaper, + DidSetWindowHasAlphaChannel, ScreenRectChanged, WM_WindowRemoved, WM_WindowStateChanged, @@ -218,6 +219,7 @@ struct WSAPI_ClientMessage { PopupMenu, DismissMenu, SetWindowIcon, + SetWindowHasAlphaChannel, }; Type type { Invalid }; int window_id { -1 }; diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp index b1dec3740d9..2f3514e0110 100644 --- a/Servers/WindowServer/WSClientConnection.cpp +++ b/Servers/WindowServer/WSClientConnection.cpp @@ -629,6 +629,24 @@ void WSClientConnection::handle_request(const WSAPISetWindowOverrideCursorReques window.set_override_cursor(WSCursor::create(request.cursor())); } +void WSClientConnection::handle_request(const WSAPISetWindowHasAlphaChannelRequest& request) +{ + int window_id = request.window_id(); + auto it = m_windows.find(window_id); + if (it == m_windows.end()) { + post_error("WSAPISetWindowHasAlphaChannelRequest: Bad window ID"); + return; + } + auto& window = *(*it).value; + window.set_has_alpha_channel(request.value()); + + WSAPI_ServerMessage response; + response.type = WSAPI_ServerMessage::Type::DidSetWindowHasAlphaChannel; + response.window_id = window_id; + response.value = request.value(); + post_message(response); +} + void WSClientConnection::handle_request(const WSWMAPISetActiveWindowRequest& request) { auto* client = WSClientConnection::from_client_id(request.target_client_id()); @@ -747,6 +765,8 @@ void WSClientConnection::on_request(const WSAPIClientRequest& request) return handle_request(static_cast(request)); case WSEvent::APIDismissMenuRequest: return handle_request(static_cast(request)); + case WSEvent::APISetWindowHasAlphaChannelRequest: + return handle_request(static_cast(request)); default: break; } diff --git a/Servers/WindowServer/WSClientConnection.h b/Servers/WindowServer/WSClientConnection.h index 3cd66a537e0..da5eeb94b01 100644 --- a/Servers/WindowServer/WSClientConnection.h +++ b/Servers/WindowServer/WSClientConnection.h @@ -77,6 +77,7 @@ private: void handle_request(const WSWMAPIStartWindowResizeRequest&); void handle_request(const WSAPIPopupMenuRequest&); void handle_request(const WSAPIDismissMenuRequest&); + void handle_request(const WSAPISetWindowHasAlphaChannelRequest&); void post_error(const String&); diff --git a/Servers/WindowServer/WSEvent.h b/Servers/WindowServer/WSEvent.h index a22dd4cb172..a7d5b21df59 100644 --- a/Servers/WindowServer/WSEvent.h +++ b/Servers/WindowServer/WSEvent.h @@ -60,6 +60,7 @@ public: APISetWallpaperRequest, APIGetWallpaperRequest, APISetWindowOverrideCursorRequest, + APISetWindowHasAlphaChannelRequest, WMAPISetActiveWindowRequest, WMAPISetWindowMinimizedRequest, WMAPIStartWindowResizeRequest, @@ -387,6 +388,23 @@ private: WSStandardCursor m_cursor { WSStandardCursor::None }; }; +class WSAPISetWindowHasAlphaChannelRequest final : public WSAPIClientRequest { +public: + explicit WSAPISetWindowHasAlphaChannelRequest(int client_id, int window_id, bool value) + : WSAPIClientRequest(WSEvent::APISetWindowHasAlphaChannelRequest, client_id) + , m_window_id(window_id) + , m_value(value) + { + } + + int window_id() const { return m_window_id; } + bool value() const { return m_value; } + +private: + int m_window_id { 0 }; + bool m_value { 0 }; +}; + class WSAPISetWallpaperRequest final : public WSAPIClientRequest { public: explicit WSAPISetWallpaperRequest(int client_id, String&& wallpaper) diff --git a/Servers/WindowServer/WSEventLoop.cpp b/Servers/WindowServer/WSEventLoop.cpp index c69722a5f6f..89449d0e622 100644 --- a/Servers/WindowServer/WSEventLoop.cpp +++ b/Servers/WindowServer/WSEventLoop.cpp @@ -244,6 +244,9 @@ bool WSEventLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessag case WSAPI_ClientMessage::Type::SetWindowOverrideCursor: post_event(client, make(client_id, message.window_id, (WSStandardCursor)message.cursor.cursor)); break; + case WSAPI_ClientMessage::SetWindowHasAlphaChannel: + post_event(client, make(client_id, message.window_id, message.value)); + break; case WSAPI_ClientMessage::Type::WM_SetActiveWindow: post_event(client, make(client_id, message.wm.client_id, message.wm.window_id)); break;