Repository: electron/electron
Pull request: feat: add `app.isHardwareAccelerationEnabled()`

#### Description of Change

This PR adds `app.isHardwareAccelerationEnabled()`, which can be used to determine whether hardware acceleration has been disabled either on the machine or via `app.disableHardwareAcceleration()`.

#### Checklist
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->

- [x] PR description included and stakeholders cc'd
- [x] `npm test` passes
- [x] tests are [changed or added](https://github.com/electron/electron/blob/main/docs/development/testing.md)
- [x] relevant API documentation, tutorials, and examples are updated and follow the [documentation style guide](https://github.com/electron/electron/blob/main/docs/development/style-guide.md)
- [x] [PR release notes](https://github.com/electron/clerk/blob/main/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/main/README.md#examples).

#### Release Notes

Notes: Added `app.isHardwareAccelerationEnabled()`

Changed files:
filename: docs/api/app.md
patch: @@ -1215,6 +1215,13 @@ Disables hardware acceleration for current app.
 
 This method can only be called before app is ready.
 
+### `app.isHardwareAccelerationEnabled()`
+
+Returns `boolean` - whether hardware acceleration is currently disabled.
+
+ > [!NOTE]
+ > This information is only usable after the `gpu-info-update` event is emitted.
+
 ### `app.disableDomainBlockingFor3DAPIs()`
 
 By default, Chromium disables 3D APIs (e.g. WebGL) until restart on a per

filename: shell/browser/api/electron_api_app.cc
patch: @@ -1140,13 +1140,24 @@ void App::DisableHardwareAcceleration(gin_helper::ErrorThrower thrower) {
         "before app is ready");
     return;
   }
+
+  // If the GpuDataManager is already initialized, disable hardware
+  // acceleration immediately. Otherwise, set a flag to disable it in
+  // OnPreCreateThreads().
   if (content::GpuDataManager::Initialized()) {
     content::GpuDataManager::GetInstance()->DisableHardwareAcceleration();
   } else {
     disable_hw_acceleration_ = true;
   }
 }
 
+bool App::IsHardwareAccelerationEnabled() {
+  if (content::GpuDataManager::Initialized())
+    return content::GpuDataManager::GetInstance()
+        ->HardwareAccelerationEnabled();
+  return !disable_hw_acceleration_;
+}
+
 void App::DisableDomainBlockingFor3DAPIs(gin_helper::ErrorThrower thrower) {
   if (Browser::Get()->is_ready()) {
     thrower.ThrowError(
@@ -1926,6 +1937,8 @@ gin::ObjectTemplateBuilder App::GetObjectTemplateBuilder(v8::Isolate* isolate) {
                  &App::SetAccessibilitySupportEnabled)
       .SetMethod("disableHardwareAcceleration",
                  &App::DisableHardwareAcceleration)
+      .SetMethod("isHardwareAccelerationEnabled",
+                 &App::IsHardwareAccelerationEnabled)
       .SetMethod("disableDomainBlockingFor3DAPIs",
                  &App::DisableDomainBlockingFor3DAPIs)
       .SetMethod("getFileIcon", &App::GetFileIcon)

filename: shell/browser/api/electron_api_app.h
patch: @@ -213,6 +213,7 @@ class App final : public gin::Wrappable<App>,
   void ReleaseSingleInstanceLock();
   bool Relaunch(gin::Arguments* args);
   void DisableHardwareAcceleration(gin_helper::ErrorThrower thrower);
+  bool IsHardwareAccelerationEnabled();
   void DisableDomainBlockingFor3DAPIs(gin_helper::ErrorThrower thrower);
   bool IsAccessibilitySupportEnabled();
   v8::Local<v8::Value> GetAccessibilitySupportFeatures();

filename: spec/api-app-spec.ts
patch: @@ -149,6 +149,12 @@ describe('app module', () => {
     });
   });
 
+  describe('app.isHardwareAccelerationEnabled()', () => {
+    it('should be a boolean', () => {
+      expect(app.isHardwareAccelerationEnabled()).to.be.a('boolean');
+    });
+  });
+
   describe('app.isPackaged', () => {
     it('should be false during tests', () => {
       expect(app.isPackaged).to.equal(false);