Skip to content

Screenshot and screen recorder shell support - #3

Open
wayne-tbl wants to merge 50 commits into
FuriLabs:forkyfrom
wayne-tbl:screen-capture
Open

Screenshot and screen recorder shell support#3
wayne-tbl wants to merge 50 commits into
FuriLabs:forkyfrom
wayne-tbl:screen-capture

Conversation

@wayne-tbl

@wayne-tbl wayne-tbl commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

The shell side of the two capture quick settings. Updated again at review request (27 Aug): the interface is now io.furios.Shell. Earlier (18 Aug) the exported symbols went away and the plugin moved to D-Bus. The quick settings themselves live in FuriLabs/furios-phosh-plugins#2.

src/phosh-exported-symbols.txt.in is byte-identical to forky again, so nothing here can be caught out by an upstream ABI change.

  • shell: add a helper to fold the top panel — the shell already folds the drawer on lock, from inside phosh_shell_set_locked(); this lifts it into a function so the screenshot manager can do the same. Not exported; called from within the shell only.
  • screenshot-manager: open the shot from its notification — click to open in the default image viewer, with a thumbnail of what was captured.
  • screenshot-manager: add a delayed screenshot — otherwise a shot taken from the quick settings is a picture of the quick settings. The countdown runs in a silent transient notification, closed 350 ms before the shutter: the banner is a layer surface like any other and a shot taken sooner catches it on its way out.
  • screenshot-manager: add a FuriOS interface for the delayed screenshotnew. io.furios.Shell.ScreenshotDelayed(u delay), which folds the drawer and starts the countdown, returning as soon as the countdown starts.
  • shell: add the screen capture gsettings — the screenshot delay, and the recorder's framerate, speed, codec, bitrate, audio source and touch drawing.

Why a new interface rather than a method on org.gnome.Shell.Screenshot

Same reasoning applied to the layer-shell protocol: that interface is defined upstream and is not ours to add methods to. This one is exported on the same bus name and the same object path (/org/gnome/Shell/Screenshot), so a caller needs no second lookup — just a different interface name on the same object. phosh already ships io.furios.Flashlightd.xml, so the namespace is not new here.

Named io.furios.Shell rather than io.furios.Shell.Screenshot at review request, so that later FuriOS-specific shell additions have a home already exported and need no second interface. The generated type is PhoshDBusFuriosShell, which does not collide with GNOME's PhoshDBusScreenshot.

Why the schema stays here

io.furios.phosh.shell is phosh's schema and a second package cannot extend it, so the keys cannot travel with the plugins. They are also read by the Settings panel (FuriLabs/gnome-control-center#5) whether or not the plugin package is installed.

Note on the power button

This adds a screenshot path; it does not replace one. src/power-menu-manager.c is untouched on every branch in this series and the power-button screenshot works exactly as before.

Pairs with FuriLabs/phoc#2: the Show Touches option writes phoc's touch-points key and is inert until that lands.
Needed by furios-phosh-plugins#2, which cannot build until this is merged and libphosh-0.45-dev rebuilt from it.

5 commits, off forky. Builds clean on an FLX1.

agx and others added 30 commits June 17, 2026 18:27
We need newer ashpd in Debian for that

This reverts commit 0b9b65a.
These architectures have too many exported symbols
This is can be used to get the pixel format of the image, as returned
by the compositor.

Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
This function can be used to ensure an eventual BGR format can be
converted to RGB so that cairo is happy.

Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
… it's in ARGB format

Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
for night light, we use PQ which is not the standard way gnome expects, this works either way. let this one slide

Signed-off-by: Bardia Moshiri <fakeshell@bardia.tech>
Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
…dw-gtk3 as well

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
on our device the frame is captured too quickly while the power menu is still open. wait a bit and try again

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
we run phoc 0.44.0 with a few patches to run with wlroots 0.17.4 before we rebase to 0.18.x and this option doesn't exist on that version. let it slide for now

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Disables lock screen and non-app panels. Meant for first time setup
set default HWCOMPOSER-1 scale to the value used by g-c-c's "275%"
…se fails

it is very sad that we are resorting to this and i really dislike this piece of code.
lomiri apps (and potentially builds from e.g chum or open repos) are built against a set of toolkits we do not control. for the most part this is fine since most the dependencies are already packaged (or to be packaged) but we don't fork certain things like upstream maintainers do (such as qt)
this leads us down a very dark road. since upstream has essentially custom everything, we have to hack in support for certain things to work [1][2] and this change is yet another hack to make things compatible.
the issue we have here is that appid detection is not exactly standard in any toolkit and system. while gtk and lately qt6 are unifying this, for the most part old qt5 apps either never set the appid or set something that does not represent the app itself.
qmlscene in lomiri is a good example, any app using morph will spawn a process for webapp-container inside qmlscene which then sets its own title and appid, that is besides qmlscene also adding a .qmlscene to the end of appid
then we have cases where the desktop file has the format {developer}.{appname} but the appid says {appname}.{developer} and some even have extra prefixes. in general nothing in consistent
this change will allow the script we generate for each app to set a appid as the fallback for the spawning process using gsettings and phosh will respect that as a last resort if everything else fails (gsettings set io.furios.phosh.shell appid 'org.example.App.desktop').
this key is the reset by phosh itself to not conflict with future apps if they do not set any appid and they also reach a fallback state. this is the cleanest solution i can come up with, with other solutions involving us forking the toolkit and forcing some ugly behaviour that might break apps that are do not come from the open store

[1] https://github.com/FuriLabs/furios-lomiri-app-support
[2] https://github.com/FuriLabs/store-provider/blob/503cfe3850620d9788c833eb07f5525c849b6c85/open_store/click.py#L201

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
…-ids key

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
required for setting backlight brightness after DPM change

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
…anager

required for setting backlight brightness after DPM change

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
…mode changed

on some kernel drivers the screen does not turn off by setting DPM and it has to be done manually through sysfs.
set brightness to 0 on DPM off and restore to previously known good state on DPM on

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
FakeShell and others added 15 commits June 17, 2026 18:33
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
initialize the output stream binding during widget setup instead of waiting for the next active-output-update signal.
this keeps the volume slider synchronized with external volume changes even when no output device change happen after startup

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
some audio routes are exposed as ports on the current sink/source rather than separate audio devices.

when selecting such routes, change the stream port in addition to the selected device, allowing switching between ports on the same sink/source

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
audio routes exposed as ports on the same sink/source do not emit active-input-update or active-output-update when switching between ports.
store the port associated with each audio device and listen for notify::port on the current stream.
update the active device state based on the stream's active port so the selected audio route is reflected correctly in the UI.

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
in case user does not upgrade phosh and gnome session together, this saves the device from getting in an unbootable state

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
tests do not work nicely with our CI machines (or maybe wlroots?) so lets drop that for now

Signed-off-by: Bardia Moshiri <fakeshell@bardia.tech>
not the most nuclear option, but definitely up there next to `exec 2>/dev/null; command >/dev/null 2>&1; exec 2>&2` =)

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
as discussed: "its a stupid notification, its not actionable and if you start an app and it doesnt start well you know that cause it ain't there."

Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
Signed-off-by: Bardia Moshiri <bardia@furilabs.com>
@wayne-tbl wayne-tbl changed the title Screenshot and screen recorder quick settings Screenshot and screen recorder shell support Aug 17, 2026
The shell already folds the settings drawer on lock, from inside
phosh_shell_set_locked(). Lift that into a function of its own so the
screenshot manager can do the same: a screenshot requested from the
drawer has to get the drawer out of the picture before it shoots.

Not exported. It is called from within the shell only.

Signed-off-by: wayne <wayne@furilabs.com>
Clicking the notification opens the file in the default image viewer, and
the notification carries a thumbnail of what was captured.

Signed-off-by: wayne <wayne@furilabs.com>
A screenshot taken from the quick settings would otherwise be a picture of
the quick settings. The delay is counted down in a silent, transient
notification, which is closed 350ms before the shutter -- the banner is a
layer surface like any other, and a shot taken any sooner catches it on
its way out.

Signed-off-by: wayne <wayne@furilabs.com>
@wayne-tbl

Copy link
Copy Markdown
Contributor Author

ScreenshotDelayed now exercised on hardware. Returns immediately, the shell-owned timer survives the caller and fires, valid 1080x2416 PNG written.

The first attempt failed against a blanked screen and exposed an upstream defect: maybe_screencopy_done() completes the D-Bus invocation with no NULL guard and returns without disposing self->frames, so any failed screenshot refuses every later one until phosh restarts. That code is byte-identical to forky, so it does not come from this branch. Fixed in #7.

The screenshot quick setting needs two things the shell alone can do:
fold the settings drawer away, and run the countdown somewhere that
outlives the drawer. Reaching those from a plugin by exporting
phosh_shell_fold_top_panel() and the manager's delayed screenshot would
put fork-only symbols in libphosh's export list, which upstream is free
to break at any ABI bump. D-Bus costs nothing here and does not.

The method goes on a new io.furios.Shell rather than onto
org.gnome.Shell.Screenshot: that interface is defined upstream and is not
ours to add methods to. The interface is named for the shell rather than
for the screenshot so that later FuriOS-specific additions have a home
already exported, needing no second interface. It is exported on the same
bus name and object path as the GNOME ones, so a caller needs no second
lookup to reach it.

Signed-off-by: wayne <wayne@furilabs.com>
The screenshot delay, and the recorder's framerate, speed, codec,
bitrate, audio source and touch drawing. The quick settings that write
them ship separately, in furios-phosh-plugins, but the schema belongs
here: io.furios.phosh.shell is phosh's, a second package cannot extend
it, and the Settings panel reads these keys whether or not the plugins
are installed.

Signed-off-by: wayne <wayne@furilabs.com>
@FakeShell
FakeShell force-pushed the forky branch 2 times, most recently from fadf47d to 2a5f394 Compare September 10, 2026 01:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants