mirror of https://github.com/bsnes-emu/bsnes.git
Update to v101r06 release.
byuu says: I reworked the video sizing code. Ended up wasting five fucking hours fighting GTK. When you call `gtk_widget_set_size_request`, it doesn't actually happen then. This is kind of a big deal because when I then go to draw onto the viewport, the actual viewport child window is still the old size, so the image gets distorted. It recovers in a frame or so with emulation, but if we were to put a still image on there, it would stay distorted. The first thought is, `while(gtk_events_pending()) gtk_main_iteration_do(false);` right after the `set_size_request`. But nope, it tells you there's no events pending. So then you think, go deeper, use `XPending()` instead. Same thing, GTK hasn't actually issued the command to Xlib yet. So then you think, if the widget is realized, just call a blocking `gtk_main_iteration`. One call does nothing, two calls results in a deadlock on the second one ... do it before program startup, and the main window will never appear. Great. Oh, and it's not just the viewport. It's also the widget container area of the windows, as well as the window itself, as well as the fullscreen mode toggle effect. They all do this. For the latter three, I couldn't find anything that worked, so I just added 20ms loops of constantly calling `gtk_main_iteration_do(false)` after each one of those things. The downside here is toggling the status bar takes 40ms, so you'll see it and it'll feel a tiny bit sluggish. But I can't have a 20ms wait on each widget resize, that would be catastrophic to performance on windows with lots of widgets. I tried hooking configure-event and size-allocate, but they were very unreliable. So instead I ended up with a loop that waits up to a maximm of 20ms that inspects the `widget->allocation.(width,height)` values directly and waits for them to be what we asked for with `set_size_request`. There was some extreme ugliness in GTK with calling `gtk_main_iteration_do` recursively (`hiro::Widget::setGeometry` is called recursively), so I had to lock it to only happen on the top level widgets (the child ones should get resized while waiting on the top-level ones, so it should be fine in practice), and also only run it on realized widgets. Even still, I'm getting ~3 timeouts when opening the settings dialog in higan, but no other windows. But, this is the best I can do for now. And the reason for all of this pain? Yeah, updated the video code. So the Emulator::Interface now has this: struct VideoSize { uint width, height; }; //or requiem for a tuple auto videoSize() -> VideoSize; auto videoSize(uint width, uint height, bool arc) -> VideoSize; The first function, for now, is just returning the literal surface size. I may remove this ... one thing I want to allow for is cores that send different texture sizes based on interlace/hires/overscan/etc settings. The second function is more interesting. Instead of having the UI trying to figure out sizing, I figure the emulation cores can do a better job and we can customize it per-core now. So it gets the window's width and height, and whether the user asked for aspect correction, and then computes the best width/height ratio possible. For now they're all just doing multiples of a 1x scale to the UI 2x,3x,4x modes. We still need a third function, which will probably be what I repurpose videoSize() for: to return the 'effective' size for pixel shaders, to then feed into ruby, to then feed into quark, to then feed into our shaders. Since shaders use normalized coordinates for pixel fetching, this should work out just fine. The real texture size will be exposed to quark shaders as well, of course. Now for the main window ... it's just hard-coded to be 640x480, 960x720, 1280x960 for now. It works nicely for some cores on some modes, not so much for others. Work in progress I guess. I also took the opportunity to draw the about dialog box logo on the main window. Got a bit fancy and used the old spherical gradient and impose functionality of nall/image on it. Very minor highlight, nothing garish. Just something nicer than a solid black window. If you guys want to mess around with sizes, placements, and gradient styles/colors/shapes ... feel free. If you come up with something nicer, do share. That's what led to all the GTK hell ... the logo wasn't drawing right as you resized the window. But now it is, though I am not at all happy with the hacking I had to do. I also had to improve the video update code as a result of this: - when you unload a game, it blacks out the screen - if you are not quitting the emulator, it'll draw the logo; if you are, it won't - when you load a game, it black out the logo These options prevent any unsightliness from resizing the viewport with image data on it already I need to redraw the logo when toggling fullscreen with no game loaded as well for Windows, it seems.
This commit is contained in:
parent
ac2d0ba1cf
commit
427bac3011
|
@ -12,7 +12,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "101.05";
|
||||
static const string Version = "101.06";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
|
|
@ -6,10 +6,7 @@ struct Interface {
|
|||
struct Information {
|
||||
string manufacturer;
|
||||
string name;
|
||||
uint width;
|
||||
uint height;
|
||||
bool overscan;
|
||||
double aspectRatio;
|
||||
bool resettable;
|
||||
struct Capability {
|
||||
bool states;
|
||||
|
@ -70,6 +67,9 @@ struct Interface {
|
|||
virtual auto title() -> string = 0;
|
||||
|
||||
//video information
|
||||
struct VideoSize { uint width, height; };
|
||||
virtual auto videoSize() -> VideoSize = 0;
|
||||
virtual auto videoSize(uint width, uint height, bool arc) -> VideoSize = 0;
|
||||
virtual auto videoFrequency() -> double = 0;
|
||||
virtual auto videoColors() -> uint32 = 0;
|
||||
virtual auto videoColor(uint32 color) -> uint64 = 0;
|
||||
|
|
|
@ -10,10 +10,7 @@ Interface::Interface() {
|
|||
|
||||
information.manufacturer = "Nintendo";
|
||||
information.name = "Famicom";
|
||||
information.width = 256;
|
||||
information.height = 240;
|
||||
information.overscan = true;
|
||||
information.aspectRatio = 8.0 / 7.0;
|
||||
information.resettable = true;
|
||||
|
||||
information.capability.states = true;
|
||||
|
@ -54,6 +51,17 @@ auto Interface::title() -> string {
|
|||
return cartridge.title();
|
||||
}
|
||||
|
||||
auto Interface::videoSize() -> VideoSize {
|
||||
return {256, 240};
|
||||
}
|
||||
|
||||
auto Interface::videoSize(uint width, uint height, bool arc) -> VideoSize {
|
||||
uint w = 256 * (arc ? 8.0 / 7.0 : 1.0);
|
||||
uint h = 240;
|
||||
uint m = min(width / w, height / h);
|
||||
return {w * m, h * m};
|
||||
}
|
||||
|
||||
auto Interface::videoFrequency() -> double {
|
||||
return 21477272.0 / (262.0 * 1364.0 - 4.0);
|
||||
}
|
||||
|
|
|
@ -25,9 +25,13 @@ struct Interface : Emulator::Interface {
|
|||
|
||||
auto manifest() -> string override;
|
||||
auto title() -> string override;
|
||||
|
||||
auto videoSize() -> VideoSize override;
|
||||
auto videoSize(uint width, uint height, bool arc) -> VideoSize override;
|
||||
auto videoFrequency() -> double override;
|
||||
auto videoColors() -> uint32 override;
|
||||
auto videoColor(uint32 color) -> uint64 override;
|
||||
|
||||
auto audioFrequency() -> double override;
|
||||
|
||||
auto loaded() -> bool override;
|
||||
|
|
|
@ -11,10 +11,7 @@ Interface::Interface() {
|
|||
|
||||
information.manufacturer = "Nintendo";
|
||||
information.name = "Game Boy";
|
||||
information.width = 160;
|
||||
information.height = 144;
|
||||
information.overscan = false;
|
||||
information.aspectRatio = 1.0;
|
||||
information.resettable = false;
|
||||
|
||||
information.capability.states = true;
|
||||
|
@ -48,6 +45,17 @@ auto Interface::title() -> string {
|
|||
return cartridge.title();
|
||||
}
|
||||
|
||||
auto Interface::videoSize() -> VideoSize {
|
||||
return {160, 144};
|
||||
}
|
||||
|
||||
auto Interface::videoSize(uint width, uint height, bool arc) -> VideoSize {
|
||||
uint w = 160;
|
||||
uint h = 144;
|
||||
uint m = min(width / w, height / h);
|
||||
return {w * m, h * m};
|
||||
}
|
||||
|
||||
auto Interface::videoFrequency() -> double {
|
||||
return 4194304.0 / (154.0 * 456.0);
|
||||
}
|
||||
|
|
|
@ -24,9 +24,13 @@ struct Interface : Emulator::Interface {
|
|||
|
||||
auto manifest() -> string override;
|
||||
auto title() -> string override;
|
||||
|
||||
auto videoSize() -> VideoSize override;
|
||||
auto videoSize(uint width, uint height, bool arc) -> VideoSize override;
|
||||
auto videoFrequency() -> double override;
|
||||
auto videoColors() -> uint32 override;
|
||||
auto videoColor(uint32 color) -> uint64 override;
|
||||
|
||||
auto audioFrequency() -> double override;
|
||||
|
||||
auto loaded() -> bool override;
|
||||
|
|
|
@ -10,10 +10,7 @@ Interface::Interface() {
|
|||
|
||||
information.manufacturer = "Nintendo";
|
||||
information.name = "Game Boy Advance";
|
||||
information.width = 240;
|
||||
information.height = 160;
|
||||
information.overscan = false;
|
||||
information.aspectRatio = 1.0;
|
||||
information.resettable = false;
|
||||
|
||||
information.capability.states = true;
|
||||
|
@ -49,6 +46,17 @@ auto Interface::title() -> string {
|
|||
return cartridge.title();
|
||||
}
|
||||
|
||||
auto Interface::videoSize() -> VideoSize {
|
||||
return {240, 160};
|
||||
}
|
||||
|
||||
auto Interface::videoSize(uint width, uint height, bool arc) -> VideoSize {
|
||||
uint w = 240;
|
||||
uint h = 160;
|
||||
uint m = min(width / w, height / h);
|
||||
return {w * m, h * m};
|
||||
}
|
||||
|
||||
auto Interface::videoFrequency() -> double {
|
||||
return 16777216.0 / (228.0 * 1232.0);
|
||||
}
|
||||
|
|
|
@ -22,9 +22,13 @@ struct Interface : Emulator::Interface {
|
|||
|
||||
auto manifest() -> string override;
|
||||
auto title() -> string override;
|
||||
|
||||
auto videoSize() -> VideoSize override;
|
||||
auto videoSize(uint width, uint height, bool arc) -> VideoSize override;
|
||||
auto videoFrequency() -> double override;
|
||||
auto videoColors() -> uint32 override;
|
||||
auto videoColor(uint32 color) -> uint64 override;
|
||||
|
||||
auto audioFrequency() -> double override;
|
||||
|
||||
auto loaded() -> bool override;
|
||||
|
|
|
@ -10,10 +10,7 @@ Interface::Interface() {
|
|||
|
||||
information.manufacturer = "Sega";
|
||||
information.name = "Mega Drive";
|
||||
information.width = 320;
|
||||
information.height = 240;
|
||||
information.overscan = true;
|
||||
information.aspectRatio = 1.0;
|
||||
information.resettable = true;
|
||||
|
||||
information.capability.states = false;
|
||||
|
@ -52,6 +49,17 @@ auto Interface::title() -> string {
|
|||
return cartridge.title();
|
||||
}
|
||||
|
||||
auto Interface::videoSize() -> VideoSize {
|
||||
return {1280, 480};
|
||||
}
|
||||
|
||||
auto Interface::videoSize(uint width, uint height, bool arc) -> VideoSize {
|
||||
uint w = 320;
|
||||
uint h = 240;
|
||||
uint m = min(width / w, height / h);
|
||||
return {w * m, h * m};
|
||||
}
|
||||
|
||||
auto Interface::videoFrequency() -> double {
|
||||
return 60.0;
|
||||
}
|
||||
|
|
|
@ -23,9 +23,13 @@ struct Interface : Emulator::Interface {
|
|||
|
||||
auto manifest() -> string override;
|
||||
auto title() -> string override;
|
||||
|
||||
auto videoSize() -> VideoSize override;
|
||||
auto videoSize(uint width, uint height, bool arc) -> VideoSize override;
|
||||
auto videoFrequency() -> double override;
|
||||
auto videoColors() -> uint32 override;
|
||||
auto videoColor(uint32 color) -> uint64 override;
|
||||
|
||||
auto audioFrequency() -> double override;
|
||||
|
||||
auto loaded() -> bool override;
|
||||
|
|
|
@ -12,10 +12,7 @@ Interface::Interface() {
|
|||
|
||||
information.manufacturer = "Nintendo";
|
||||
information.name = "Super Famicom";
|
||||
information.width = 256;
|
||||
information.height = 240;
|
||||
information.overscan = true;
|
||||
information.aspectRatio = 8.0 / 7.0;
|
||||
information.resettable = true;
|
||||
|
||||
information.capability.states = true;
|
||||
|
@ -132,6 +129,17 @@ auto Interface::title() -> string {
|
|||
return cartridge.title();
|
||||
}
|
||||
|
||||
auto Interface::videoSize() -> VideoSize {
|
||||
return {512, 480};
|
||||
}
|
||||
|
||||
auto Interface::videoSize(uint width, uint height, bool arc) -> VideoSize {
|
||||
uint w = 256 * (arc ? 8.0 / 7.0 : 1.0);
|
||||
uint h = 240;
|
||||
uint m = min(width / w, height / h);
|
||||
return {w * m, h * m};
|
||||
}
|
||||
|
||||
auto Interface::videoFrequency() -> double {
|
||||
switch(system.region()) { default:
|
||||
case System::Region::NTSC: return (system.colorburst() * 6.0) / (262.0 * 1364.0 - 4.0);
|
||||
|
|
|
@ -40,9 +40,13 @@ struct Interface : Emulator::Interface {
|
|||
|
||||
auto manifest() -> string override;
|
||||
auto title() -> string override;
|
||||
|
||||
auto videoSize() -> VideoSize override;
|
||||
auto videoSize(uint width, uint height, bool arc) -> VideoSize override;
|
||||
auto videoFrequency() -> double override;
|
||||
auto videoColors() -> uint32 override;
|
||||
auto videoColor(uint32 color) -> uint64 override;
|
||||
|
||||
auto audioFrequency() -> double override;
|
||||
|
||||
auto loaded() -> bool override;
|
||||
|
|
|
@ -200,40 +200,37 @@ auto Presentation::updateEmulator() -> void {
|
|||
}
|
||||
|
||||
auto Presentation::resizeViewport() -> void {
|
||||
int width = emulator ? emulator->information.width : 256;
|
||||
int height = emulator ? emulator->information.height : 240;
|
||||
double stretch = emulator ? emulator->information.aspectRatio : 1.0;
|
||||
if(stretch != 1.0) {
|
||||
//aspect correction is always enabled in fullscreen mode
|
||||
if(!fullScreen() && !settings["Video/AspectCorrection"].boolean()) stretch = 1.0;
|
||||
}
|
||||
|
||||
int scale = 2;
|
||||
uint scale = 2;
|
||||
if(settings["Video/Scale"].text() == "Small" ) scale = 2;
|
||||
if(settings["Video/Scale"].text() == "Medium") scale = 3;
|
||||
if(settings["Video/Scale"].text() == "Large" ) scale = 4;
|
||||
|
||||
int windowWidth = 0, windowHeight = 0;
|
||||
uint windowWidth = 0, windowHeight = 0;
|
||||
bool aspectCorrection = true;
|
||||
if(!fullScreen()) {
|
||||
windowWidth = 320 * scale;
|
||||
windowHeight = 240 * scale;
|
||||
aspectCorrection = settings["Video/AspectCorrection"].boolean();
|
||||
} else {
|
||||
windowWidth = geometry().width();
|
||||
windowHeight = geometry().height();
|
||||
}
|
||||
|
||||
int multiplier = min(windowWidth / (int)(width * stretch), windowHeight / height);
|
||||
width = width * multiplier * stretch;
|
||||
height = height * multiplier;
|
||||
|
||||
if(!fullScreen()) setSize({windowWidth, windowHeight});
|
||||
viewport.setGeometry({(windowWidth - width) / 2, (windowHeight - height) / 2, width, height});
|
||||
|
||||
if(!emulator) drawSplashScreen();
|
||||
if(!emulator) {
|
||||
viewport.setGeometry({0, 0, windowWidth, windowHeight});
|
||||
draw(Resource::Logo::higan);
|
||||
} else {
|
||||
auto videoSize = emulator->videoSize(windowWidth, windowHeight, aspectCorrection);
|
||||
viewport.setGeometry({
|
||||
(windowWidth - videoSize.width) / 2, (windowHeight - videoSize.height) / 2,
|
||||
videoSize.width, videoSize.height
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
auto Presentation::toggleFullScreen() -> void {
|
||||
if(fullScreen() == false) {
|
||||
if(!fullScreen()) {
|
||||
menuBar.setVisible(false);
|
||||
statusBar.setVisible(false);
|
||||
setResizable(true);
|
||||
|
@ -251,15 +248,33 @@ auto Presentation::toggleFullScreen() -> void {
|
|||
resizeViewport();
|
||||
}
|
||||
|
||||
auto Presentation::drawSplashScreen() -> void {
|
||||
auto Presentation::draw(image logo) -> void {
|
||||
if(!video) return;
|
||||
|
||||
uint32_t* output;
|
||||
uint length;
|
||||
if(video->lock(output, length, 256, 240)) {
|
||||
for(auto y : range(240)) {
|
||||
auto dp = output + y * (length >> 2);
|
||||
for(auto x : range(256)) *dp++ = 0xff000000;
|
||||
uint length = 0;
|
||||
uint width = viewport.geometry().width();
|
||||
uint height = viewport.geometry().height();
|
||||
if(video->lock(output, length, width, height)) {
|
||||
uint cx = (width - logo.width()) - 10;
|
||||
uint cy = (height - logo.height()) - 10;
|
||||
|
||||
image backdrop;
|
||||
backdrop.allocate(width, height);
|
||||
if(logo && !program->hasQuit) {
|
||||
backdrop.sphericalGradient(0xff0000bf, 0xff000000, logo.width(), logo.height() / 2, width, height);
|
||||
backdrop.impose(image::blend::sourceAlpha, cx, cy, logo, 0, 0, logo.width(), logo.height());
|
||||
} else {
|
||||
backdrop.fill(0xff000000);
|
||||
}
|
||||
|
||||
auto data = (uint32_t*)backdrop.data();
|
||||
for(auto y : range(height)) {
|
||||
auto dp = output + y * (length >> 2);
|
||||
auto sp = data + y * width;
|
||||
for(auto x : range(width)) *dp++ = *sp++;
|
||||
}
|
||||
|
||||
video->unlock();
|
||||
video->refresh();
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ struct Presentation : Window {
|
|||
auto updateEmulator() -> void;
|
||||
auto resizeViewport() -> void;
|
||||
auto toggleFullScreen() -> void;
|
||||
auto drawSplashScreen() -> void;
|
||||
auto draw(image logo = {}) -> void;
|
||||
auto loadShaders() -> void;
|
||||
|
||||
MenuBar menuBar{this};
|
||||
|
|
|
@ -29,6 +29,7 @@ auto Program::loadMedium(Emulator::Interface& interface, const Emulator::Interfa
|
|||
}
|
||||
updateAudioDriver();
|
||||
updateAudioEffects();
|
||||
presentation->draw();
|
||||
emulator->power();
|
||||
|
||||
presentation->resizeViewport();
|
||||
|
@ -44,12 +45,14 @@ auto Program::loadMedium(Emulator::Interface& interface, const Emulator::Interfa
|
|||
auto Program::unloadMedium() -> void {
|
||||
if(!emulator) return;
|
||||
|
||||
presentation->draw();
|
||||
toolsManager->cheatEditor.saveCheats();
|
||||
emulator->unload();
|
||||
emulator = nullptr;
|
||||
mediumPaths.reset();
|
||||
|
||||
presentation->drawSplashScreen();
|
||||
presentation->resizeViewport();
|
||||
presentation->draw(Resource::Logo::higan);
|
||||
presentation->setTitle({"higan v", Emulator::Version});
|
||||
presentation->systemMenu.setVisible(false);
|
||||
presentation->toolsMenu.setVisible(false);
|
||||
|
|
|
@ -31,7 +31,7 @@ Program::Program(string_vector args) {
|
|||
video->set(Video::Synchronize, settings["Video/Synchronize"].boolean());
|
||||
if(!video->init()) video = Video::create("None");
|
||||
|
||||
presentation->drawSplashScreen();
|
||||
presentation->draw(Resource::Logo::higan);
|
||||
|
||||
audio = Audio::create(settings["Audio/Driver"].text());
|
||||
audio->set(Audio::Device, settings["Audio/Device"].text());
|
||||
|
@ -87,6 +87,7 @@ auto Program::main() -> void {
|
|||
}
|
||||
|
||||
auto Program::quit() -> void {
|
||||
hasQuit = true;
|
||||
unloadMedium();
|
||||
settings.quit();
|
||||
inputManager->quit();
|
||||
|
|
|
@ -36,6 +36,7 @@ struct Program : Emulator::Interface::Bind {
|
|||
auto updateAudioDriver() -> void;
|
||||
auto updateAudioEffects() -> void;
|
||||
|
||||
bool hasQuit = false;
|
||||
bool pause = false;
|
||||
|
||||
vector<Emulator::Interface*> emulators;
|
||||
|
|
|
@ -10,10 +10,7 @@ Interface::Interface() {
|
|||
|
||||
information.manufacturer = "Bandai";
|
||||
information.name = "WonderSwan";
|
||||
information.width = 224; //note: technically 224x144; but screen can be rotated
|
||||
information.height = 224; //by using a square size; this can be done in the core
|
||||
information.overscan = false;
|
||||
information.aspectRatio = 1.0;
|
||||
information.resettable = false;
|
||||
|
||||
information.capability.states = true;
|
||||
|
@ -54,6 +51,17 @@ auto Interface::title() -> string {
|
|||
return cartridge.information.title;
|
||||
}
|
||||
|
||||
auto Interface::videoSize() -> VideoSize {
|
||||
return {224, 224};
|
||||
}
|
||||
|
||||
auto Interface::videoSize(uint width, uint height, bool arc) -> VideoSize {
|
||||
uint w = 224;
|
||||
uint h = 224;
|
||||
uint m = min(width / w, height / h);
|
||||
return {w * m, h * m};
|
||||
}
|
||||
|
||||
auto Interface::videoFrequency() -> double {
|
||||
return 3072000.0 / (159.0 * 256.0); //~75.47hz
|
||||
}
|
||||
|
|
|
@ -24,9 +24,13 @@ struct Interface : Emulator::Interface {
|
|||
|
||||
auto manifest() -> string override;
|
||||
auto title() -> string override;
|
||||
|
||||
auto videoSize() -> VideoSize override;
|
||||
auto videoSize(uint width, uint height, bool arc) -> VideoSize override;
|
||||
auto videoFrequency() -> double override;
|
||||
auto videoColors() -> uint32;
|
||||
auto videoColor(uint32 color) -> uint64;
|
||||
|
||||
auto audioFrequency() -> double override;
|
||||
|
||||
auto loaded() -> bool override;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <nall/platform.hpp>
|
||||
#include <nall/chrono.hpp>
|
||||
#include <nall/directory.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/image.hpp>
|
||||
|
@ -203,6 +204,8 @@ struct Position {
|
|||
|
||||
Position();
|
||||
Position(signed x, signed y);
|
||||
template<typename X, typename Y>
|
||||
Position(X x, Y y) : Position((signed)x, (signed)y) {}
|
||||
|
||||
explicit operator bool() const;
|
||||
auto operator==(const Position& source) const -> bool;
|
||||
|
@ -230,6 +233,8 @@ struct Size {
|
|||
|
||||
Size();
|
||||
Size(signed width, signed height);
|
||||
template<typename W, typename H>
|
||||
Size(W width, H height) : Size((signed)width, (signed)height) {}
|
||||
|
||||
explicit operator bool() const;
|
||||
auto operator==(const Size& source) const -> bool;
|
||||
|
@ -261,6 +266,8 @@ struct Geometry {
|
|||
Geometry();
|
||||
Geometry(Position position, Size size);
|
||||
Geometry(signed x, signed y, signed width, signed height);
|
||||
template<typename X, typename Y, typename W, typename H>
|
||||
Geometry(X x, Y y, W width, H height) : Geometry((signed)x, (signed)y, (signed)width, (signed)height) {}
|
||||
|
||||
explicit operator bool() const;
|
||||
auto operator==(const Geometry& source) const -> bool;
|
||||
|
|
|
@ -41,7 +41,23 @@ auto pWidget::setFont(const Font& font) -> void {
|
|||
auto pWidget::setGeometry(Geometry geometry) -> void {
|
||||
if(!gtkWidget) return;
|
||||
if(gtkParent) gtk_fixed_move(GTK_FIXED(gtkParent), gtkWidget, geometry.x(), geometry.y());
|
||||
gtk_widget_set_size_request(gtkWidget, max(1, geometry.width()), max(1, geometry.height()));
|
||||
if(geometry.width() < 1) geometry.setWidth (1);
|
||||
if(geometry.height() < 1) geometry.setHeight(1);
|
||||
gtk_widget_set_size_request(gtkWidget, geometry.width(), geometry.height());
|
||||
if(gtk_widget_get_realized(gtkWidget)) {
|
||||
static bool locked = false;
|
||||
if(!locked) {
|
||||
locked = true;
|
||||
auto time = chrono::millisecond();
|
||||
while(chrono::millisecond() - time < 20) {
|
||||
gtk_main_iteration_do(false);
|
||||
if(gtkWidget->allocation.width != geometry.width ()) continue;
|
||||
if(gtkWidget->allocation.height != geometry.height()) continue;
|
||||
break;
|
||||
}
|
||||
locked = false;
|
||||
}
|
||||
}
|
||||
self().doSize();
|
||||
}
|
||||
|
||||
|
|
|
@ -266,6 +266,8 @@ auto pWindow::setFullScreen(bool fullScreen) -> void {
|
|||
gtk_window_unfullscreen(GTK_WINDOW(widget));
|
||||
state().geometry = windowedGeometry;
|
||||
}
|
||||
auto time = chrono::millisecond();
|
||||
while(chrono::millisecond() - time < 20) gtk_main_iteration_do(false);
|
||||
}
|
||||
|
||||
auto pWindow::setGeometry(Geometry geometry) -> void {
|
||||
|
@ -278,7 +280,12 @@ auto pWindow::setGeometry(Geometry geometry) -> void {
|
|||
gtk_window_set_geometry_hints(GTK_WINDOW(widget), GTK_WIDGET(widget), &geom, GDK_HINT_MIN_SIZE);
|
||||
|
||||
gtk_widget_set_size_request(formContainer, geometry.width(), geometry.height());
|
||||
auto time1 = chrono::millisecond();
|
||||
while(chrono::millisecond() - time1 < 20) gtk_main_iteration_do(false);
|
||||
|
||||
gtk_window_resize(GTK_WINDOW(widget), geometry.width(), geometry.height() + _menuHeight() + _statusHeight());
|
||||
auto time2 = chrono::millisecond();
|
||||
while(chrono::millisecond() - time2 < 20) gtk_main_iteration_do(false);
|
||||
}
|
||||
|
||||
auto pWindow::setModal(bool modal) -> void {
|
||||
|
|
|
@ -44,8 +44,8 @@ struct pWindow : pObject {
|
|||
GtkWidget* gtkMenu = nullptr;
|
||||
GtkWidget* gtkStatus = nullptr;
|
||||
GtkAllocation lastAllocation = {0};
|
||||
bool onSizePending = false;
|
||||
Geometry windowedGeometry{128, 128, 256, 256};
|
||||
bool onSizePending = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue