Skip to content

Commit

Permalink
Merge branch 'master' into x11-put-clipboard2
Browse files Browse the repository at this point in the history
  • Loading branch information
psychon committed Jul 8, 2021
2 parents 6b0fde9 + 52f257b commit c385063
Show file tree
Hide file tree
Showing 75 changed files with 305 additions and 178 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,11 @@ jobs:
steps:
- uses: actions/checkout@v2

# libgtk-dev seems to be needed by e.g. druid-derive
- name: install libgtk-dev
# libx11-dev is needed by druid-derive as dev dependency
- name: install libx11-dev
run: |
sudo apt update
sudo apt install libgtk-3-dev
sudo apt install libx11-dev libpango1.0-dev libxkbcommon-dev libxkbcommon-x11-dev
if: contains(matrix.os, 'ubuntu')

- name: install wasm-pack
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ You can find its changes [documented below](#070---2021-01-01).
- X11 backend now supports custom cursors ([#1801] by [@psychon])
- X11: Add support for transparent windows ([#1803] by [@psychon])
- X11: Added support for `get_monitors` ([#1804] by [@psychon])
- x11: Remove some unnecessary casts ([#1851] by [@psychon])
- `has_focus` method on `WidgetPod` ([#1825] by [@ForLoveOfCats])
- x11: Add support for getting and setting clipboard contents ([#1805] and [#1851] by [@psychon])
- Linux extension: primary_clipboard ([#1843] by [@Maan2003])

### Changed

Expand All @@ -62,6 +64,7 @@ You can find its changes [documented below](#070---2021-01-01).
- Window size and positioning code is now in display points ([#1713] by [@jneem])
- Update look and feel of controls when disabled ([#1717] by [@xarvic])
- Change the signature of `add_idle_callback` ([#1787] by [@jneem])
- Move macOS only function to Mac extension trait ([#1863] by [@Maan2003])

### Deprecated

Expand Down Expand Up @@ -738,7 +741,9 @@ Last release without a changelog :(
[#1805]: https://github.com/linebender/druid/pull/1805
[#1820]: https://github.com/linebender/druid/pull/1820
[#1825]: https://github.com/linebender/druid/pull/1825
[#1843]: https://github.com/linebender/druid/pull/1843
[#1851]: https://github.com/linebender/druid/pull/1851
[#1863]: https://github.com/linebender/druid/pull/1863

[Unreleased]: https://github.com/linebender/druid/compare/v0.7.0...master
[0.7.0]: https://github.com/linebender/druid/compare/v0.6.0...v0.7.0
Expand Down
2 changes: 1 addition & 1 deletion druid-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ quote = "1.0.7"
proc-macro2 = "1.0.19"

[dev-dependencies]
druid = { version = "0.7.0", path = "../druid" }
druid = { version = "0.7.0", path = "../druid", default-features = false, features = ["x11"] }

float-cmp = { version = "0.8.0", features = ["std"], default-features = false }
10 changes: 5 additions & 5 deletions druid-shell/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ by [druid], a UI toolkit.

The code in `druid-shell` can be divided into roughly two categories: the
platform agnostic code and types, which are exposed directly, and the
platform-specific implementations of these types, which live in per-platform
directories in `src/platform`. The platform-specific code for the current
platform is reexported as `druid-shell::platform`.
platform-specific implementations of these types, which live in per-backend
directories in `src/backend`. The backend-specific code for the current
backend is reexported as `druid-shell::backend`.

`druid-shell` does not generally expose platform types directly. Instead, we
`druid-shell` does not generally expose backend types directly. Instead, we
expose wrapper structs that define the common interface, and then call
corresponding methods on the concrete type for the current platform.
corresponding methods on the concrete type for the current backend.

## Unsafe

Expand Down
41 changes: 8 additions & 33 deletions druid-shell/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ use std::cell::RefCell;
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};

use crate::backend::application as backend;
use crate::clipboard::Clipboard;
use crate::error::Error;
use crate::platform::application as platform;
use crate::util;

/// A top-level handler that is not associated with any window.
Expand All @@ -47,7 +47,7 @@ pub trait AppHandler {
/// This can be thought of as a reference and it can be safely cloned.
#[derive(Clone)]
pub struct Application {
pub(crate) platform_app: platform::Application,
pub(crate) backend_app: backend::Application,
state: Rc<RefCell<State>>,
}

Expand Down Expand Up @@ -79,12 +79,9 @@ impl Application {
.compare_exchange(false, true, Ordering::AcqRel, Ordering::Acquire)
.map_err(|_| Error::ApplicationAlreadyExists)?;
util::claim_main_thread();
let platform_app = platform::Application::new()?;
let backend_app = backend::Application::new()?;
let state = Rc::new(RefCell::new(State { running: false }));
let app = Application {
platform_app,
state,
};
let app = Application { backend_app, state };
GLOBAL_APP.with(|global_app| {
*global_app.borrow_mut() = Some(app.clone());
});
Expand Down Expand Up @@ -150,7 +147,7 @@ impl Application {
}

// Run the platform application
self.platform_app.run(handler);
self.backend_app.run(handler);

// This application is no longer active, so clear the global reference
GLOBAL_APP.with(|global_app| {
Expand All @@ -170,34 +167,12 @@ impl Application {
///
/// [`run`]: #method.run
pub fn quit(&self) {
self.platform_app.quit()
}

// TODO: do these three go in some kind of PlatformExt trait?
/// Hide the application this window belongs to. (cmd+H)
pub fn hide(&self) {
#[cfg(target_os = "macos")]
self.platform_app.hide()
}

/// Hide all other applications. (cmd+opt+H)
pub fn hide_others(&self) {
#[cfg(target_os = "macos")]
self.platform_app.hide_others()
}

/// Sets the global application menu, on platforms where there is one.
///
/// On platforms with no global application menu, this has no effect.
#[allow(unused_variables)]
pub fn set_menu(&self, menu: crate::Menu) {
#[cfg(target_os = "macos")]
self.platform_app.set_menu(menu.into_inner());
self.backend_app.quit()
}

/// Returns a handle to the system clipboard.
pub fn clipboard(&self) -> Clipboard {
self.platform_app.clipboard().into()
self.backend_app.clipboard().into()
}

/// Returns the current locale string.
Expand All @@ -206,6 +181,6 @@ impl Application {
///
/// [Unicode language identifier]: https://unicode.org/reports/tr35/#Unicode_language_identifier
pub fn get_locale() -> String {
platform::Application::get_locale()
backend::Application::get_locale()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,20 @@ impl Application {
}

pub fn clipboard(&self) -> Clipboard {
Clipboard
Clipboard {
selection: gdk::SELECTION_CLIPBOARD,
}
}

pub fn get_locale() -> String {
glib::get_language_names()[0].as_str().into()
}
}

impl crate::platform::linux::LinuxApplicationExt for crate::Application {
fn primary_clipboard(&self) -> crate::Clipboard {
crate::Clipboard(Clipboard {
selection: gdk::SELECTION_PRIMARY,
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,29 @@ const CLIPBOARD_TARGETS: [&str; 5] = [
];

/// The system clipboard.
#[derive(Debug, Clone)]
pub struct Clipboard;
#[derive(Clone)]
pub struct Clipboard {
pub(crate) selection: Atom,
}

impl std::fmt::Debug for Clipboard {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name = match self.selection {
gdk::SELECTION_PRIMARY => "Primary",
gdk::SELECTION_CLIPBOARD => "Clipboard",
_ => "(other)",
};
f.debug_tuple("Clipboard").field(&name).finish()
}
}

impl Clipboard {
/// Put a string onto the system clipboard.
pub fn put_string(&mut self, string: impl AsRef<str>) {
let string = string.as_ref().to_string();

let display = gdk::Display::get_default().unwrap();
let clipboard = gtk::Clipboard::get_default(&display).unwrap();
let clipboard = gtk::Clipboard::get_for_display(&display, &self.selection);

let targets: Vec<TargetEntry> = CLIPBOARD_TARGETS
.iter()
Expand All @@ -55,7 +68,7 @@ impl Clipboard {
pub fn put_formats(&mut self, formats: &[ClipboardFormat]) {
let entries = make_entries(formats);
let display = gdk::Display::get_default().unwrap();
let clipboard = gtk::Clipboard::get_default(&display).unwrap();
let clipboard = gtk::Clipboard::get_for_display(&display, &self.selection);
// this is gross: we need to reclone all the data in formats in order
// to move it into the closure. :/
let formats = formats.to_owned();
Expand Down Expand Up @@ -83,7 +96,7 @@ impl Clipboard {
/// Get a string from the system clipboard, if one is available.
pub fn get_string(&self) -> Option<String> {
let display = gdk::Display::get_default().unwrap();
let clipboard = gtk::Clipboard::get_default(&display).unwrap();
let clipboard = gtk::Clipboard::get_for_display(&display, &self.selection);

for target in &CLIPBOARD_TARGETS {
let atom = Atom::intern(target);
Expand All @@ -99,7 +112,7 @@ impl Clipboard {
/// highest priority on the system clipboard, or `None` if no types are supported.
pub fn preferred_format(&self, formats: &[FormatId]) -> Option<FormatId> {
let display = gdk::Display::get_default().unwrap();
let clipboard = gtk::Clipboard::get_default(&display).unwrap();
let clipboard = gtk::Clipboard::get_for_display(&display, &self.selection);
let targets = clipboard.wait_for_targets()?;
let format_atoms = formats
.iter()
Expand All @@ -119,7 +132,7 @@ impl Clipboard {
/// [`Clipboard::preferred_format`]
pub fn get_format(&self, format: FormatId) -> Option<Vec<u8>> {
let display = gdk::Display::get_default().unwrap();
let clipboard = gtk::Clipboard::get_default(&display).unwrap();
let clipboard = gtk::Clipboard::get_for_display(&display, &self.selection);
let atom = Atom::intern(format);
clipboard
.wait_for_contents(&atom)
Expand All @@ -128,7 +141,7 @@ impl Clipboard {

pub fn available_type_names(&self) -> Vec<String> {
let display = gdk::Display::get_default().unwrap();
let clipboard = gtk::Clipboard::get_default(&display).unwrap();
let clipboard = gtk::Clipboard::get_for_display(&display, &self.selection);
let targets = clipboard.wait_for_targets().unwrap_or_default();
targets
.iter()
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! GTK platform errors.
//! GTK backend errors.

use std::fmt;

use glib::{BoolError, Error as GLibError};

/// GTK platform errors.
/// GTK backend errors.
#[derive(Debug, Clone)]
pub enum Error {
/// Generic GTK error.
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! GTK-based platform support
//! GTK-based backend support

pub mod application;
pub mod clipboard;
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ use super::keycodes;
use super::menu::Menu;
use super::util;

/// The platform target DPI.
/// The backend target DPI.
///
/// GTK considers 96 the default value which represents a 1.0 scale factor.
const SCALE_TARGET_DPI: f64 = 96.0;
Expand Down Expand Up @@ -145,7 +145,7 @@ enum IdleKind {
}

// We use RefCells for interior mutability, but we try to structure things so that double-borrows
// are impossible. See the documentation on crate::platform::x11::window::Window for more details,
// are impossible. See the documentation on crate::backend::x11::window::Window for more details,
// since the idea there is basically the same.
pub(crate) struct WindowState {
window: ApplicationWindow,
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ use crate::application::AppHandler;

use super::clipboard::Clipboard;
use super::error::Error;
use super::menu::Menu;
use super::util;

static APP_HANDLER_IVAR: &str = "druidAppHandler";
Expand Down Expand Up @@ -102,28 +101,6 @@ impl Application {
}
}

/// Hide the application this window belongs to. (cmd+H)
pub fn hide(&self) {
unsafe {
let () = msg_send![self.ns_app, hide: nil];
}
}

/// Hide all other applications. (cmd+opt+H)
pub fn hide_others(&self) {
unsafe {
let workspace = class!(NSWorkspace);
let shared: id = msg_send![workspace, sharedWorkspace];
let () = msg_send![shared, hideOtherApplications];
}
}

pub fn set_menu(&self, menu: Menu) {
unsafe {
NSApp().setMainMenu_(menu.menu);
}
}

pub fn clipboard(&self) -> Clipboard {
Clipboard
}
Expand All @@ -142,6 +119,28 @@ impl Application {
}
}

impl crate::platform::mac::MacApplicationExt for crate::Application {
fn hide(&self) {
unsafe {
let () = msg_send![self.backend_app.ns_app, hide: nil];
}
}

fn hide_others(&self) {
unsafe {
let workspace = class!(NSWorkspace);
let shared: id = msg_send![workspace, sharedWorkspace];
let () = msg_send![shared, hideOtherApplications];
}
}

fn set_menu(&self, menu: crate::Menu) {
unsafe {
NSApp().setMainMenu_(menu.0.menu);
}
}
}

struct DelegateState {
handler: Option<Box<dyn AppHandler>>,
}
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub(crate) unsafe fn build_panel(ty: FileDialogType, mut options: FileDialogOpti
if options.select_directories {
let () = msg_send![panel, setCanChooseDirectories: YES];
// Disable the selection of files in directory selection mode,
// because other platforms like Windows have no support for it,
// because other backends like Windows have no support for it,
// and expecting it to work will lead to buggy cross-platform behavior.
let () = msg_send![panel, setCanChooseFiles: NO];
// File filters are used by macOS to determine which paths are packages.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! macOS platform errors.
//! macOS backend errors.

//TODO: add a platform error for macOS, based on NSError
//TODO: add a backend error for macOS, based on NSError

#[derive(Debug, Clone)]
pub struct Error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! Conversion of platform keyboard event into cross-platform event.
//! Conversion of backend keyboard event into cross-platform event.

use cocoa::appkit::{NSEvent, NSEventModifierFlags, NSEventType};
use cocoa::base::id;
Expand Down
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit c385063

Please sign in to comment.