Skip to content

Commit

Permalink
Refactor fullscreen and maximized window logic.
Browse files Browse the repository at this point in the history
The new foreign interface architecture handles the state of the relevant window
slots (fullscreen-p, maximized-p) instead of setf-ing them on the renderer
packages.  This replaces the need for the :skip-renderer-resize keyword.

Fixed bug in toggle-message-buffer, where the height of the buffer was being
probed incorrectly.

Refactor the handling of the window-state-event in GTK.  It didn't account for
events where the window is no longer fullscreen or maximized.

Simplify implementation of toggle-fullscreen, toggle-maximize,
toggle-status-buffer and toggle-message-buffer.

As for the fullscreen rationale regarding the UI: when a fullscreen event is
emitted by JS's Fullscreen API, the status and message buffers are hidden.  For
all other fullscreen events, the status and message buffers are kept.  Note that
we can't hide the message buffer on fullscreen since then there would be no way
to get that important piece of information.  On typical browsers, the equivalent
of the message buffer is a dynamically visible toolbar at the bottom left (and
it is still displayed on fullscreen).
  • Loading branch information
aadcg committed Jul 25, 2024
1 parent 8cef6df commit 8947a77
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 76 deletions.
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)))

0 comments on commit 8947a77

Please sign in to comment.