Comments (8)
Hey,
It's good to see people discovering this project and the first issue being created :)
Actually this was on my TODO list for like a few weeks since I realized font being too small while recording GIFs for README.md. About the XSetFont()
approach, you're basically right. That's one way of setting the font size. (the font, actually) So I've played around with it a little bit in get_gc
function which is responsible for the main graphics context:
fn get_gc(&self, fg_color: u64) -> xlib::GC {
let font = "-*-dejavu sans-*-*-*-*-17-*-*-*-*-*-*-*"; // font description
let font = CString::new(font).expect("Failed to create CString");
let xfont =
unsafe { xlib::XLoadQueryFont(self.display.inner, font.as_ptr()) }; // load font
unsafe {
let gc =
xlib::XCreateGC(self.display.inner, self.xid, 0, ptr::null_mut());
xlib::XSetForeground(self.display.inner, gc, fg_color);
if !xfont.is_null() {
xlib::XSetFont(self.display.inner, gc, (*xfont).fid); // set font
} else {
warn!("Invalid font!"); // TODO: do this somewhere else, get_gc is called for every new window
}
gc
}
}
Result:
Turns out it can indeed set the font but the only problem being finding the correct font query/description. In this case, I generated the -*-dejavu sans-*-*-*-*-17-*-*-*-*-*-*-*
description with using xfontsel
utility:
Give xfontsel
utility a try. Not all of the fonts support a specific size so format!(-*-*-*-*-*-*-{}-*-*-*-*-*-*-*, font_size)
might not load a font at all. (thinking aloud)
So my plan is to implement a separate font handler function/module and adding the --font
flag to general settings for letting user to set a font according to the X11 font descriptions. (e.g. menyoki --font "-*-*-*-*-*-*-17-*-*-*-*-*-*-*"
)
Tell me what you think :)
from menyoki.
It's not exactly easy to find fonts that are actually big enough on my system, but this does in fact work.
It's also revealed that Window
leaks an astounding amount of GCs; they're 176 bytes each, so it's not a giagnti deal memory-wise and I was gonna say that "it makes menyoki use 5% of my CPU" when idling, but applying the diff below reveals that removing overhead from the continuous allocations actually makes the program use 9% instead, as it spins in polls and redraws. This probably explains why it's so weird and flickery?
diff --git a/Cargo.lock b/Cargo.lock
index f976f92..8713a39 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -717,6 +717,7 @@ dependencies = [
"image 0.23.12",
"imgref",
"kamadak-exif",
+ "lazy_static",
"log",
"natord",
"png 0.16.7",
diff --git a/Cargo.toml b/Cargo.toml
index f5562c9..2ff0915 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -52,6 +52,7 @@ natord = "1.0.9"
colored = "2.0.0"
log = "0.4.11"
fern_colored = { version = "0.6.1", features = ["colored"] }
+lazy_static = "1.4.0"
[dependencies.clap]
version = "2.33.3"
diff --git a/src/main.rs b/src/main.rs
index 184cc92..ac1e8e4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,6 +3,8 @@
#[macro_use]
extern crate log;
+#[macro_use]
+extern crate lazy_static;
mod analyze;
mod anim;
diff --git a/src/x11/window.rs b/src/x11/window.rs
index 1eeb01d..aec0639 100644
--- a/src/x11/window.rs
+++ b/src/x11/window.rs
@@ -5,12 +5,14 @@ use crate::window::Capture;
use crate::x11::display::Display;
use image::Bgra;
use std::convert::{TryFrom, TryInto};
+use std::sync::Mutex;
use std::ffi::CString;
use std::fmt;
use std::io::{self, Write};
use std::mem::MaybeUninit;
use std::ptr;
use std::slice;
+use std::collections::BTreeMap;
use textwidth::Context;
use x11::xlib;
@@ -19,6 +21,12 @@ const MAX_TEXT_HEIGHT: u32 = 30;
/* Offset for placing the text on the corner of window */
const TEXT_CORNER_OFFSET: i32 = 20;
+struct GcWrapper(xlib::GC);
+unsafe impl Send for GcWrapper {}
+lazy_static! {
+ static ref GC_CACHE: Mutex<BTreeMap<u64, GcWrapper>> = Mutex::new(BTreeMap::new());
+}
+
/* X11 window id, geometric properties and its display */
#[derive(Clone, Copy, Debug)]
pub struct Window {
@@ -26,6 +34,7 @@ pub struct Window {
display: Display,
pub geometry: Geometry,
pub area: Geometry,
+ gc: xlib::GC,
}
/* Implementations for thread-safe usage */
@@ -60,6 +69,7 @@ impl Window {
display,
geometry: Geometry::default(),
area: Geometry::default(),
+ gc: ptr::null_mut(),
}
.set_geometry()
}
@@ -132,12 +142,13 @@ impl Window {
* @return GC
*/
fn get_gc(&self, fg_color: u64) -> xlib::GC {
- unsafe {
- let gc =
- xlib::XCreateGC(self.display.inner, self.xid, 0, ptr::null_mut());
- xlib::XSetForeground(self.display.inner, gc, fg_color);
- gc
- }
+ GC_CACHE.lock().unwrap().entry(self.xid).or_insert_with(|| {
+ unsafe {
+ let gc = xlib::XCreateGC(self.display.inner, self.xid, 0, ptr::null_mut());
+ xlib::XSetForeground(self.display.inner, gc, fg_color);
+ GcWrapper(gc)
+ }
+ }).0
}
/* Draw a rectangle inside the window. */
from menyoki.
It's not exactly easy to find fonts that are actually big enough on my system, but this does in fact work.
I'm thinking of adding a --font
argument to record and capture for setting the font. (If that partly solves your issue.) Better than nothing I guess.
Besides, I don't know what else we can do about this.
It's also revealed that
Window
leaks an astounding amount of GCs; they're 176 bytes each, so it's not a giagnti deal memory-wise and I was gonna say that "it makes menyoki use 5% of my CPU" when idling, but applying the diff below reveals that removing overhead from the continuous allocations actually makes the program use 9% instead, as it spins in polls and redraws. This probably explains why it's so weird and flickery?
Flickering happens because it attemps to clear the window area when the selection (rectangle) moved or resized (also window content affects it as well I guess.) And yeah, creating GCs continuously is the reason of that CPU usage. I should re-evaluate the select_window function some time.
What's the weird part? I might be blind enough to not see that since I've been using menyoki for months.
from menyoki.
Yeah, being able to specify the font in the config would definitely solve this.
The weirdness got a little less weird when I killed my compositor, since my wallpaper shone through the green rectangle edges (and text, funnily enough, when moving the selection) otherwise, but combined with the screen tearing it does look quite odd as it redraws over the course of a few frames after blinking off when hovering over a link in firefox.
from menyoki.
Yeah, being able to specify the font in the config would definitely solve this.
Great!
The weirdness got a little less weird when I killed my compositor, since my wallpaper shone through the green rectangle edges (and text, funnily enough, when moving the selection) otherwise, but combined with the screen tearing it does look quite odd as it redraws over the course of a few frames after blinking off when hovering over a link in firefox.
Hmm, I'd like to look into that and solve it (if it's possible) if you can provide something visual.
from menyoki.
In https://youtu.be/pHBuUCFsEeA, note how the text is partially white as it moves around and as short lines shine through the borders as they come in, matching what's behind them in the root window (https://nabijaczleweli.xyz/content/maths/wiggly-circle.html#r0_sngllines2_flagpan_1600x900_60).
from menyoki.
With the latest release (v0.1.4), you can specify the font (--font
) and border width (--border
) while using record or capture. (also they are available in config file and as environment variables)
Test it out. You can close the issue if there's nothing else to do :)
from menyoki.
Yep, that works; thanks!
from menyoki.
Related Issues (20)
- RUSTSEC-2020-0071: Potential segfault in the time crate
- RUSTSEC-2022-0013: Regexes with large repetitions on empty sub-expressions take a very long time to parse HOT 1
- RUSTSEC-2022-0006: Data race in `Iter` and `IterMut` HOT 1
- RUSTSEC-2020-0163: `term_size` is unmaintained; use `terminal_size` instead
- RUSTSEC-2021-0139: ansi_term is Unmaintained HOT 2
- webp recording throwing an error HOT 1
- Support recording WebP
- Support pause during recording
- Expand shell expressions for files HOT 2
- Recording the mouse pointer HOT 1
- Adaptive framerate
- Support recording WebM
- Include a way to select a capture zone with the cursor
- CLI is awkward to use HOT 1
- Support lodepng for encoding PNGs
- The duration argument (-d <S>) doesn't seem to work HOT 5
- Cancelling action should produce exit status HOT 5
- Ctrl+c does not work to stop during the saving of the gif. HOT 2
- Stop recording throw an error and does not generate any gif HOT 3
- Improve the key bindings documentation
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from menyoki.