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

Fix fullscreen and maximized logic #3441

Merged
merged 2 commits into from
Jul 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions source/changelog.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

(define-version "4.0.0"
(:ul
(:li "Fix fullscreen and maximized window logic.")
(:li "Refactor input to be handled on the buffer level rather than the window
level.")
(:li "Deprecate " (:code "input-skip-dispatcher") ".")
Expand Down
35 changes: 26 additions & 9 deletions source/foreign-interface.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,32 @@ If the `:setter-p' option is non-nil, then a dummy setf method is defined."
(define-ffi-generic ffi-window-delete (window)
(:documentation "Delete WINDOW."))

(define-ffi-generic ffi-window-fullscreen (window)
(:documentation "Set fullscreen WINDOW state on."))
(define-ffi-generic ffi-window-unfullscreen (window)
(:documentation "Set fullscreen WINDOW state off."))

(define-ffi-generic ffi-window-maximize (window)
(:documentation "Set WINDOW to a maximized state."))
(define-ffi-generic ffi-window-unmaximize (window)
(:documentation "Set WINDOW to an unmaximized state."))
(define-ffi-generic ffi-window-fullscreen (window &key &allow-other-keys)
(:method :around ((window window) &key (user-event-p t) &allow-other-keys)
(setf (slot-value window 'fullscreen-p) t)
(when user-event-p (call-next-method)))
(:documentation "Set fullscreen WINDOW state on.
USER-EVENT-P helps to distinguish events requested by the user or
renderer (e.g. fullscreen a video stream)."))
(define-ffi-generic ffi-window-unfullscreen (window &key &allow-other-keys)
(:method :around ((window window) &key (user-event-p t) &allow-other-keys)
(setf (slot-value window 'fullscreen-p) nil)
(when user-event-p (call-next-method)))
(:documentation "Set fullscreen WINDOW state off.
See `ffi-window-fullscreen'."))

(define-ffi-generic ffi-window-maximize (window &key &allow-other-keys)
(:method :around ((window window) &key (user-event-p t) &allow-other-keys)
(setf (slot-value window 'maximized-p) t)
(when user-event-p (call-next-method)))
(:documentation "Set WINDOW to a maximized state.
USER-EVENT-P helps to distinguish events requested by the user or renderer."))
(define-ffi-generic ffi-window-unmaximize (window &key &allow-other-keys)
(:method :around ((window window) &key (user-event-p t) &allow-other-keys)
(setf (slot-value window 'maximized-p) nil)
(when user-event-p (call-next-method)))
(:documentation "Set WINDOW to an unmaximized state.
See `ffi-window-maximize'."))

(define-ffi-generic ffi-buffer-url (buffer)
(:documentation "Return the URL associated with BUFFER as a `quri:uri'.
Expand Down
8 changes: 4 additions & 4 deletions source/renderer/electron.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -403,16 +403,16 @@
(defmethod ffi-width ((window electron-window))
(electron:get-bounds window 'width))

(defmethod ffi-window-fullscreen ((window electron-window))
(defmethod ffi-window-fullscreen ((window electron-window) &key &allow-other-keys)
(electron:fullscreen window))

(defmethod ffi-window-unfullscreen ((window electron-window))
(defmethod ffi-window-unfullscreen ((window electron-window) &key &allow-other-keys)
(electron:unfullscreen window))

(defmethod ffi-window-maximize ((window electron-window))
(defmethod ffi-window-maximize ((window electron-window) &key &allow-other-keys)
(electron:maximize window))

(defmethod ffi-window-unmaximize ((window electron-window))
(defmethod ffi-window-unmaximize ((window electron-window) &key &allow-other-keys)
(electron:unmaximize window))

;; Input handling
Expand Down
38 changes: 24 additions & 14 deletions source/renderer/gtk.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -500,12 +500,18 @@ response. The BODY is wrapped with `with-protect'."
(on-signal-destroy window))
(connect-signal window "window-state-event" nil (widget event)
(declare (ignore widget))
(setf (nyxt::fullscreen-p window)
(find :fullscreen
(gdk:gdk-event-window-state-new-window-state event)))
(setf (nyxt::maximized-p window)
(find :maximized
(gdk:gdk-event-window-state-new-window-state event)))
(let ((fullscreen-p)
(maximized-p))
(dolist (state (gdk:gdk-event-window-state-new-window-state event))
(case state
(:fullscreen
(setq fullscreen-p t)
(ffi-window-fullscreen window :user-event-p nil))
(:maximized
(setq maximized-p t)
(ffi-window-maximize window :user-event-p nil))))
(unless fullscreen-p (ffi-window-unfullscreen window :user-event-p nil))
(unless maximized-p (ffi-window-unmaximize window :user-event-p nil)))
nil))

(unless nyxt::*headless-p*
Expand All @@ -523,16 +529,16 @@ response. The BODY is wrapped with `with-protect'."
(define-ffi-method ffi-window-delete ((window gtk-window))
(gtk:gtk-widget-destroy (gtk-object window)))

(define-ffi-method ffi-window-fullscreen ((window gtk-window))
(define-ffi-method ffi-window-fullscreen ((window gtk-window) &key &allow-other-keys)
(gtk:gtk-window-fullscreen (gtk-object window)))

(define-ffi-method ffi-window-unfullscreen ((window gtk-window))
(define-ffi-method ffi-window-unfullscreen ((window gtk-window) &key &allow-other-keys)
(gtk:gtk-window-unfullscreen (gtk-object window)))

(define-ffi-method ffi-window-maximize ((window gtk-window))
(define-ffi-method ffi-window-maximize ((window gtk-window) &key &allow-other-keys)
(gtk:gtk-window-maximize (gtk-object window)))

(define-ffi-method ffi-window-unmaximize ((window gtk-window))
(define-ffi-method ffi-window-unmaximize ((window gtk-window) &key &allow-other-keys)
(gtk:gtk-window-unmaximize (gtk-object window)))

(defun derive-key-string (keyval character)
Expand Down Expand Up @@ -1610,13 +1616,17 @@ the `active-buffer'."
nil)
(connect-signal buffer "enter-fullscreen" nil (web-view)
(declare (ignore web-view))
(setf (nyxt::fullscreen-p (current-window)) t)
(toggle-fullscreen :skip-renderer-resize t)
(ffi-window-fullscreen (current-window) :user-event-p nil)
;; As to account for JS's Fullscreen API.
(disable-message-buffer (current-window))
(disable-status-buffer (current-window))
nil)
(connect-signal buffer "leave-fullscreen" nil (web-view)
(declare (ignore web-view))
(setf (nyxt::fullscreen-p (current-window)) nil)
(toggle-fullscreen :skip-renderer-resize t)
(ffi-window-unfullscreen (current-window) :user-event-p nil)
;; Ideally, the UI state prior to fullscreen must be recovered.
(enable-message-buffer (current-window))
(enable-status-buffer (current-window))
nil)
buffer)

Expand Down
79 changes: 30 additions & 49 deletions source/window.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -178,66 +178,47 @@ not try to quit the browser."
(window-set-buffer window buffer)
(values window buffer)))

(define-command toggle-fullscreen (&key (window (current-window))
skip-renderer-resize)
"Fullscreen WINDOW, or the current window, when omitted.
When `skip-renderer-resize' is non-nil, don't ask the renderer to fullscreen the window."
(let ((fullscreen (fullscreen-p window)))
(unless skip-renderer-resize
(if fullscreen
(ffi-window-unfullscreen window)
(ffi-window-fullscreen window)))
(toggle-status-buffer :show-p (not fullscreen))
(toggle-message-buffer :show-p (not fullscreen))))

(define-command toggle-maximize (&key (window (current-window)))
"Maximize WINDOW, or the current window, when omitted."
(let ((maximized (maximized-p window)))
(if maximized
(ffi-window-unmaximize window)
(ffi-window-maximize window))))

(define-command toggle-fullscreen (&optional (window (current-window)))
"Toggle fullscreen state of window."
(if (fullscreen-p window)
(ffi-window-unfullscreen window)
(ffi-window-fullscreen window)))

(define-command toggle-maximize (&optional (window (current-window)))
"Toggle maximized state of window."
(if (maximized-p window)
(ffi-window-unmaximize window)
(ffi-window-maximize window)))

(export-always 'enable-status-buffer)
(defun enable-status-buffer (&optional (window (current-window)))
(setf (ffi-height (status-buffer window)) (height (status-buffer window))))

(export-always 'disable-status-buffer)
(defun disable-status-buffer (&optional (window (current-window)))
(setf (ffi-height (status-buffer window)) 0))

(export-always 'enable-message-buffer)
(defun enable-message-buffer (&optional (window (current-window)))
(setf (ffi-height (message-buffer window)) (height (message-buffer window))))

(export-always 'disable-message-buffer)
(defun disable-message-buffer (&optional (window (current-window)))
(setf (ffi-height (message-buffer window)) 0))

(define-command toggle-toolbars (&optional (window (current-window)))
"Toggle the visibility of the message and status buffers."
(toggle-status-buffer :window window)
(toggle-message-buffer :window window))

(define-command toggle-status-buffer (&key (window (current-window))
(show-p nil show-provided-p))
"Toggle the visibility of the status buffer.

If SHOW-P is provided:
- If SHOW-P is T, then `status-buffer' is always enabled;
- Otherwise, it is always disabled."
(cond ((and show-provided-p show-p)
(enable-status-buffer window))
((and (not show-provided-p)
(zerop (ffi-height (status-buffer window))))
(enable-status-buffer window))
(t (disable-status-buffer window))))

(define-command toggle-message-buffer (&key (window (current-window))
(show-p nil show-provided-p))
"Toggle the visibility of the message buffer.

If SHOW-P is provided:
- If SHOW-P is T, then `message-buffer' is always enabled;
- Otherwise, it is always disabled."
(cond ((and show-provided-p show-p)
(enable-message-buffer window))
((and (not show-provided-p)
(zerop (height (message-buffer window))))
(enable-message-buffer window))
(t (disable-message-buffer window))))
(toggle-status-buffer window)
(toggle-message-buffer window))

(define-command toggle-status-buffer (&optional (window (current-window)))
"Toggle the visibility of the status buffer."
(if (zerop (ffi-height (status-buffer window)))
(enable-status-buffer window)
(disable-status-buffer window)))

(define-command toggle-message-buffer (&optional (window (current-window)))
"Toggle the visibility of the message buffer."
(if (zerop (ffi-height (message-buffer window)))
(enable-message-buffer window)
(disable-message-buffer window)))