Skip to content

Commit

Permalink
Merge pull request #727 from atom/high-dpi
Browse files Browse the repository at this point in the history
Set DPI settings from gsettings on Linux
  • Loading branch information
zcbenz committed Oct 21, 2014
2 parents b09252f + 0d19e77 commit f39224a
Show file tree
Hide file tree
Showing 8 changed files with 370 additions and 0 deletions.
4 changes: 4 additions & 0 deletions atom.gyp
Expand Up @@ -96,6 +96,7 @@
'atom/browser/atom_browser_context.h',
'atom/browser/atom_browser_main_parts.cc',
'atom/browser/atom_browser_main_parts.h',
'atom/browser/atom_browser_main_parts_linux.cc',
'atom/browser/atom_browser_main_parts_mac.mm',
'atom/browser/atom_javascript_dialog_manager.cc',
'atom/browser/atom_javascript_dialog_manager.h',
Expand Down Expand Up @@ -312,7 +313,10 @@
'chromium_src/chrome/renderer/printing/print_web_view_helper.h',
'chromium_src/chrome/renderer/tts_dispatcher.cc',
'chromium_src/chrome/renderer/tts_dispatcher.h',
'chromium_src/library_loaders/libgio_loader.cc',
'chromium_src/library_loaders/libgio.h',
'chromium_src/library_loaders/libspeechd_loader.cc',
'chromium_src/library_loaders/libspeechd.h',
'<@(native_mate_files)',
],
'framework_sources': [
Expand Down
4 changes: 4 additions & 0 deletions atom/browser/atom_browser_main_parts.cc
Expand Up @@ -50,6 +50,10 @@ brightray::BrowserContext* AtomBrowserMainParts::CreateBrowserContext() {
void AtomBrowserMainParts::PostEarlyInitialization() {
brightray::BrowserMainParts::PostEarlyInitialization();

#if defined(USE_X11)
SetDPIFromGSettings();
#endif

// The ProxyResolverV8 has setup a complete V8 environment, in order to avoid
// conflicts we only initialize our V8 environment after that.
js_env_.reset(new JavascriptEnvironment);
Expand Down
4 changes: 4 additions & 0 deletions atom/browser/atom_browser_main_parts.h
Expand Up @@ -38,6 +38,10 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
#endif

private:
#if defined(USE_X11)
void SetDPIFromGSettings();
#endif

scoped_ptr<Browser> browser_;
scoped_ptr<JavascriptEnvironment> js_env_;
scoped_ptr<NodeBindings> node_bindings_;
Expand Down
82 changes: 82 additions & 0 deletions atom/browser/atom_browser_main_parts_linux.cc
@@ -0,0 +1,82 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/atom_browser_main_parts.h"

#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "library_loaders/libgio.h"
#include "ui/gfx/switches.h"

namespace atom {

namespace {

const char* kInterfaceSchema = "org.gnome.desktop.interface";
const char* kScaleFactor = "scaling-factor";

bool SchemaExists(const LibGioLoader& libgio_loader, const char* schema_name) {
const gchar* const* schemas = libgio_loader.g_settings_list_schemas();
while (*schemas) {
if (strcmp(schema_name, static_cast<const char*>(*schemas)) == 0)
return true;
schemas++;
}
return false;
}

bool KeyExists(const LibGioLoader& libgio_loader, GSettings* client,
const char* key) {
gchar** keys = libgio_loader.g_settings_list_keys(client);
if (!keys)
return false;

gchar** iter = keys;
while (*iter) {
if (strcmp(*iter, key) == 0)
break;
iter++;
}

bool exists = *iter != NULL;
g_strfreev(keys);
return exists;
}

void GetDPIFromGSettings(guint* scale_factor) {
LibGioLoader libgio_loader;

// Try also without .0 at the end; on some systems this may be required.
if (!libgio_loader.Load("libgio-2.0.so.0") &&
!libgio_loader.Load("libgio-2.0.so")) {
VLOG(1) << "Cannot load gio library. Will fall back to gconf.";
return;
}

GSettings* client = nullptr;
if (!SchemaExists(libgio_loader, kInterfaceSchema) ||
!(client = libgio_loader.g_settings_new(kInterfaceSchema))) {
VLOG(1) << "Cannot create gsettings client.";
return;
}

if (KeyExists(libgio_loader, client, kScaleFactor))
*scale_factor = libgio_loader.g_settings_get_uint(client, kScaleFactor);

g_object_unref(client);
}

} // namespace

void AtomBrowserMainParts::SetDPIFromGSettings() {
guint scale_factor = 1;
GetDPIFromGSettings(&scale_factor);
if (scale_factor == 0)
scale_factor = 1;

base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kForceDeviceScaleFactor, base::UintToString(scale_factor));
}

} // namespace atom
2 changes: 2 additions & 0 deletions atom/browser/lib/init.coffee
Expand Up @@ -14,6 +14,8 @@ process.argv.splice 1, 1
# Pick out switches appended by atom-shell.
startMark = process.argv.indexOf '--atom-shell-switches-start'
endMark = process.argv.indexOf '--atom-shell-switches-end'
# And --force-device-scale-factor on Linux.
endMark++ if process.platform is 'linux'
process.argv.splice startMark, endMark - startMark + 1

# Add browser/api/lib to require's search paths,
Expand Down
48 changes: 48 additions & 0 deletions chromium_src/library_loaders/libgio.h
@@ -0,0 +1,48 @@
// This is generated file. Do not modify directly.
// Path to the code generator: tools/generate_library_loader/generate_library_loader.py .

#ifndef LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H
#define LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H

#include <gio/gio.h>
#define LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN


#include <string>

class LibGioLoader {
public:
LibGioLoader();
~LibGioLoader();

bool Load(const std::string& library_name)
__attribute__((warn_unused_result));

bool loaded() const { return loaded_; }

typeof(&::g_settings_new) g_settings_new;
typeof(&::g_settings_get_child) g_settings_get_child;
typeof(&::g_settings_get_string) g_settings_get_string;
typeof(&::g_settings_get_boolean) g_settings_get_boolean;
typeof(&::g_settings_get_uint) g_settings_get_uint;
typeof(&::g_settings_get_strv) g_settings_get_strv;
typeof(&::g_settings_is_writable) g_settings_is_writable;
typeof(&::g_settings_list_schemas) g_settings_list_schemas;
typeof(&::g_settings_list_keys) g_settings_list_keys;


private:
void CleanUp(bool unload);

#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN)
void* library_;
#endif

bool loaded_;

// Disallow copy constructor and assignment operator.
LibGioLoader(const LibGioLoader&);
void operator=(const LibGioLoader&);
};

#endif // LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H
174 changes: 174 additions & 0 deletions chromium_src/library_loaders/libgio_loader.cc
@@ -0,0 +1,174 @@
// This is generated file. Do not modify directly.
// Path to the code generator: tools/generate_library_loader/generate_library_loader.py .

#include "library_loaders/libgio.h"

#include <dlfcn.h>

// Put these sanity checks here so that they fire at most once
// (to avoid cluttering the build output).
#if !defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN) && !defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DT_NEEDED)
#error neither LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN nor LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DT_NEEDED defined
#endif
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN) && defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DT_NEEDED)
#error both LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN and LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DT_NEEDED defined
#endif

LibGioLoader::LibGioLoader() : loaded_(false) {
}

LibGioLoader::~LibGioLoader() {
CleanUp(loaded_);
}

bool LibGioLoader::Load(const std::string& library_name) {
if (loaded_)
return false;

#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN)
library_ = dlopen(library_name.c_str(), RTLD_LAZY);
if (!library_)
return false;
#endif


#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN)
g_settings_new =
reinterpret_cast<typeof(this->g_settings_new)>(
dlsym(library_, "g_settings_new"));
#endif
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DT_NEEDED)
g_settings_new = &::g_settings_new;
#endif
if (!g_settings_new) {
CleanUp(true);
return false;
}

#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN)
g_settings_get_child =
reinterpret_cast<typeof(this->g_settings_get_child)>(
dlsym(library_, "g_settings_get_child"));
#endif
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DT_NEEDED)
g_settings_get_child = &::g_settings_get_child;
#endif
if (!g_settings_get_child) {
CleanUp(true);
return false;
}

#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN)
g_settings_get_string =
reinterpret_cast<typeof(this->g_settings_get_string)>(
dlsym(library_, "g_settings_get_string"));
#endif
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DT_NEEDED)
g_settings_get_string = &::g_settings_get_string;
#endif
if (!g_settings_get_string) {
CleanUp(true);
return false;
}

#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN)
g_settings_get_boolean =
reinterpret_cast<typeof(this->g_settings_get_boolean)>(
dlsym(library_, "g_settings_get_boolean"));
#endif
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DT_NEEDED)
g_settings_get_boolean = &::g_settings_get_boolean;
#endif
if (!g_settings_get_boolean) {
CleanUp(true);
return false;
}

#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN)
g_settings_get_uint =
reinterpret_cast<typeof(this->g_settings_get_uint)>(
dlsym(library_, "g_settings_get_uint"));
#endif
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DT_NEEDED)
g_settings_get_uint = &::g_settings_get_uint;
#endif
if (!g_settings_get_uint) {
CleanUp(true);
return false;
}

#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN)
g_settings_get_strv =
reinterpret_cast<typeof(this->g_settings_get_strv)>(
dlsym(library_, "g_settings_get_strv"));
#endif
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DT_NEEDED)
g_settings_get_strv = &::g_settings_get_strv;
#endif
if (!g_settings_get_strv) {
CleanUp(true);
return false;
}

#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN)
g_settings_is_writable =
reinterpret_cast<typeof(this->g_settings_is_writable)>(
dlsym(library_, "g_settings_is_writable"));
#endif
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DT_NEEDED)
g_settings_is_writable = &::g_settings_is_writable;
#endif
if (!g_settings_is_writable) {
CleanUp(true);
return false;
}

#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN)
g_settings_list_schemas =
reinterpret_cast<typeof(this->g_settings_list_schemas)>(
dlsym(library_, "g_settings_list_schemas"));
#endif
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DT_NEEDED)
g_settings_list_schemas = &::g_settings_list_schemas;
#endif
if (!g_settings_list_schemas) {
CleanUp(true);
return false;
}

#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN)
g_settings_list_keys =
reinterpret_cast<typeof(this->g_settings_list_keys)>(
dlsym(library_, "g_settings_list_keys"));
#endif
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DT_NEEDED)
g_settings_list_keys = &::g_settings_list_keys;
#endif
if (!g_settings_list_keys) {
CleanUp(true);
return false;
}

loaded_ = true;
return true;
}

void LibGioLoader::CleanUp(bool unload) {
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBGIO_H_DLOPEN)
if (unload) {
dlclose(library_);
library_ = NULL;
}
#endif
loaded_ = false;
g_settings_new = NULL;
g_settings_get_child = NULL;
g_settings_get_string = NULL;
g_settings_get_boolean = NULL;
g_settings_get_uint = NULL;
g_settings_get_strv = NULL;
g_settings_is_writable = NULL;
g_settings_list_schemas = NULL;
g_settings_list_keys = NULL;

}

0 comments on commit f39224a

Please sign in to comment.