trying to fix minigui's selection hacks and shrinkiness

This commit is contained in:
Adam D. Ruppe 2024-09-28 17:08:31 -04:00
parent 161d733196
commit 1aff5c0293
3 changed files with 94 additions and 26 deletions

15
core.d
View File

@ -1480,7 +1480,7 @@ inout(char)[] stripRightInternal(return inout(char)[] s) {
}
/++
Shortcut for converting some types to string without invoking Phobos (but it will as a last resort).
Shortcut for converting some types to string without invoking Phobos (but it may as a last resort).
History:
Moved from color.d to core.d in March 2023 (dub v11.0).
@ -1500,9 +1500,18 @@ string toStringInternal(T)(T t) {
default:
return "<unknown>";
}
} else static if(is(T : const E[], E)) {
string ret = "[";
foreach(idx, e; t) {
if(idx)
ret ~= ", ";
ret ~= toStringInternal(e);
}
ret ~= "]";
return ret;
} else {
import std.conv;
return to!string(t);
static assert(0, T.stringof ~ " makes compile too slow");
// import std.conv; return to!string(t);
}
}

View File

@ -3189,8 +3189,8 @@ void recomputeChildLayout(string relevantMeasure)(Widget parent) {
if(spaceRemaining < 0 && shrinkyChildSum) {
// shrink to get into the space if it is possible
auto toRemove = -spaceRemaining;
auto removalPerItem = toRemove * shrinkinessSum / shrinkyChildSum;
auto remainder = toRemove * shrinkinessSum % shrinkyChildSum;
auto removalPerItem = toRemove / shrinkinessSum;
auto remainder = toRemove % shrinkinessSum;
// FIXME: wtf why am i shrinking things with no shrinkiness?
@ -3201,17 +3201,20 @@ void recomputeChildLayout(string relevantMeasure)(Widget parent) {
if(child.hidden)
continue;
static if(calcingV) {
auto maximum = childStyle.maxHeight();
auto minimum = childStyle.minHeight();
auto stretch = childStyle.heightShrinkiness();
} else {
auto maximum = childStyle.maxWidth();
auto minimum = childStyle.minWidth();
auto stretch = childStyle.widthShrinkiness();
}
if(mixin("child._" ~ relevantMeasure) >= maximum)
if(mixin("child._" ~ relevantMeasure) <= minimum)
continue;
// import arsd.core; writeln(typeid(child).toString, " ", child._width, " > ", minimum, " :: ", removalPerItem, "*", stretch);
mixin("child._" ~ relevantMeasure) -= removalPerItem + remainder; // this is removing more than needed to trigger the next thing. ugh.
mixin("child._" ~ relevantMeasure) -= removalPerItem * stretch + remainder / shrinkyChildSum; // this is removing more than needed to trigger the next thing. ugh.
spaceRemaining += removalPerItem + remainder;
spaceRemaining += removalPerItem * stretch + remainder / shrinkyChildSum;
}
}
@ -12101,10 +12104,14 @@ class TextDisplayHelper : Widget {
private string preservedPrimaryText;
protected void selectionChanged() {
// sdpyPrintDebugString("selectionChanged"); try throw new Exception("e"); catch(Exception e) sdpyPrintDebugString(e.toString());
static if(UsingSimpledisplayX11)
with(l.selection()) {
if(!isEmpty()) {
//sdpyPrintDebugString("!isEmpty");
getPrimarySelection(parentWindow.win, (in char[] txt) {
// sdpyPrintDebugString("getPrimarySelection: " ~ getContentString() ~ " (old " ~ txt ~ ")");
// import std.stdio; writeln("txt: ", txt, " sel: ", getContentString);
if(txt.length) {
preservedPrimaryText = txt.idup;
@ -12117,6 +12124,9 @@ class TextDisplayHelper : Widget {
}
}
final TextLayouter layouter() {
return l;
}
bool readonly;
bool caretNavigation; // scroll lock can flip this
@ -12216,7 +12226,10 @@ class TextDisplayHelper : Widget {
if(readonly) return;
getClipboardText(parentWindow.win, (txt) {
doStateCheckpoint();
l.selection.replaceContent(txt);
if(singleLine)
l.selection.replaceContent(txt.stripInternal());
else
l.selection.replaceContent(txt);
adjustScrollbarSizes();
scrollForCaret();
this.redraw();
@ -12816,8 +12829,13 @@ abstract class EditableTextWidget : EditableTextWidgetParent {
@property void content(string s) {
if(useCustomWidget) {
version(use_new_text_system) {
selectAll();
textLayout.selection.replaceContent(s);
with(textLayout.selection) {
moveToStartOfDocument();
setAnchor();
moveToEndOfDocument();
setFocus();
replaceContent(s);
}
tdh.adjustScrollbarSizes();
// these don't seem to help
@ -13185,7 +13203,8 @@ class LineEdit : EditableTextWidget {
override bool showingVerticalScroll() { return false; }
override bool showingHorizontalScroll() { return false; }
override int flexBasisWidth() { return 250; }
override int flexBasisWidth() { return 250; }
override int widthShrinkiness() { return 10; }
///
this(Widget parent) {

View File

@ -6689,9 +6689,31 @@ version(X11) {
else static if (atomName == "SECONDARY") Atom a = XA_SECONDARY;
else Atom a = GetAtom!atomName(display);
XSetSelectionOwner(display, a, window.impl.window, 0 /* CurrentTime */);
if(auto ptr = a in window.impl.setSelectionHandlers) {
// we already have it, don't even need to inform the X server
// sdpyPrintDebugString("short circuit in set");
*ptr = data;
} else {
// we don't have it, tell X we want it
XSetSelectionOwner(display, a, window.impl.window, 0 /* CurrentTime */);
window.impl.setSelectionHandlers[a] = data;
}
}
window.impl.setSelectionHandlers[a] = data;
/++
History:
Added September 28, 2024
+/
bool hasX11Selection(string atomName)(SimpleWindow window) {
auto display = XDisplayConnection.get();
static if (atomName == "PRIMARY") Atom a = XA_PRIMARY;
else static if (atomName == "SECONDARY") Atom a = XA_SECONDARY;
else Atom a = GetAtom!atomName(display);
if(a in window.impl.setSelectionHandlers)
return true;
else
return false;
}
///
@ -6775,6 +6797,17 @@ version(X11) {
}
}
if(auto ptr = atom in window.impl.setSelectionHandlers) {
if(auto txt = (cast(X11SetSelectionHandler_Text) *ptr)) {
// we already have it! short circuit everything
// sdpyPrintDebugString("short circuit in get");
handler(cast(char[]) txt.text_original);
return;
}
}
window.impl.getSelectionHandlers[atom] = new X11GetSelectionHandler_Text(handler);
auto target = GetAtom!"TARGETS"(display);
@ -15789,6 +15822,7 @@ version(X11) {
switch(e.type) {
case EventType.SelectionClear:
// writeln("SelectionClear");
if(auto win = e.xselectionclear.window in SimpleWindow.nativeMapping) {
// FIXME so it is supposed to finish any in progress transfers... but idk...
// writeln("SelectionClear");
@ -15805,7 +15839,7 @@ version(X11) {
}
break;
case EventType.PropertyNotify:
// printf("PropertyNotify %s %d\n", XGetAtomName(e.xproperty.display, e.xproperty.atom), e.xproperty.state);
// import core.stdc.stdio; printf("PropertyNotify %s %d\n", XGetAtomName(e.xproperty.display, e.xproperty.atom), e.xproperty.state);
foreach(ssh; SimpleWindow.impl.setSelectionHandlers) {
if(ssh.matchesIncr(e.xproperty.window, e.xproperty.atom) && e.xproperty.state == PropertyNotification.PropertyDelete)
@ -15849,8 +15883,9 @@ version(X11) {
}
break;
case EventType.SelectionNotify:
if(auto win = e.xselection.requestor in SimpleWindow.nativeMapping)
if(auto handler = e.xproperty.atom in win.getSelectionHandlers) {
// import std.stdio; writefln("SelectionNotify %06x %06x", e.xselection.requestor, e.xproperty.atom);
if(auto win = e.xselection.requestor in SimpleWindow.nativeMapping)
if(auto handler = e.xproperty.atom in win.getSelectionHandlers) {
if(e.xselection.property == None) { // || e.xselection.property == GetAtom!("NULL", true)(e.xselection.display)) {
XUnlockDisplay(display);
scope(exit) XLockDisplay(display);
@ -15924,7 +15959,7 @@ version(X11) {
*/
}
}
break;
break;
case EventType.ConfigureNotify:
auto event = e.xconfigure;
if(auto win = event.window in SimpleWindow.nativeMapping) {
@ -18413,8 +18448,7 @@ struct Visual
}
override void scrollWheel(NSEvent event) @selector("scrollWheel:") {
import std.stdio;
writeln(event.deltaY);
// import std.stdio; writeln(event.deltaY);
}
override void keyDown(NSEvent event) @selector("keyDown:") {
@ -20064,12 +20098,12 @@ unittest {
7, 8
]);
import std.conv;
//import std.conv;
m *= m2;
assert(m.data == [
19, 22,
43, 50
], to!string(m.data));
]);//, to!string(m.data));
}
@ -23023,7 +23057,9 @@ __gshared bool librariesSuccessfullyLoaded = true;
__gshared bool openGlLibrariesSuccessfullyLoaded = true;
private mixin template DynamicLoadSupplementalOpenGL(Iface) {
mixin(staticForeachReplacement!Iface);
// mixin(staticForeachReplacement!Iface);
static foreach(name; __traits(derivedMembers, Iface))
mixin("__gshared typeof(&__traits(getMember, Iface, name)) " ~ name ~ ";");
void loadDynamicLibrary() @nogc {
(cast(void function() @nogc) &loadDynamicLibraryForReal)();
@ -23038,6 +23074,7 @@ private mixin template DynamicLoadSupplementalOpenGL(Iface) {
}
}
/+
private const(char)[] staticForeachReplacement(Iface)() pure {
/*
// just this for gdc 9....
@ -23067,9 +23104,12 @@ private const(char)[] staticForeachReplacement(Iface)() pure {
return code[0 .. pos];
}
+/
private mixin template DynamicLoad(Iface, string library, int majorVersion, alias success) {
mixin(staticForeachReplacement!Iface);
//mixin(staticForeachReplacement!Iface);
static foreach(name; __traits(derivedMembers, Iface))
mixin("__gshared typeof(&__traits(getMember, Iface, name)) " ~ name ~ ";");
private __gshared void* libHandle;
private __gshared bool attempted;